### Install SPADE using setup.py Source: https://github.com/javipalanca/spade/wiki/Home Install SPADE by running the setup.py script directly from the package source. This method is useful for development or custom installations. ```bash python setup.py install ``` -------------------------------- ### Install Development Dependencies with uv Source: https://github.com/javipalanca/spade/blob/master/CONTRIBUTING.rst Install the project and its development dependencies using uv, the recommended package manager. ```shell cd spade/ uv sync --extra dev ``` -------------------------------- ### Install SPADE using easy_install Source: https://github.com/javipalanca/spade/wiki/Home Install the SPADE library using the easy_install tool. This is an alternative to pip. ```bash easy_install SPADE ``` -------------------------------- ### Example of pip installation error for SPADE Source: https://github.com/javipalanca/spade/wiki/Installation-on-Windows-8.1-with-python-2.7.9-64-bit This output shows the error encountered when attempting a standard pip installation of SPADE, highlighting issues with missing modules like 'resource' and the 'pexpect' dependency not supporting Windows. ```text pip.exe install SPADE Downloading/unpacking SPADE Running setup.py (path:c:\users\saint\appdata\local\temp\pip_build_Saint\SPADE\setup.py) egg_info for package SPADE package init file 'xmppd\socker\__init__.py' not found (or not a regular file) Downloading/unpacking pexpect (from SPADE) Running setup.py (path:c:\users\saint\appdata\local\temp\pip_build_Saint\pexpect\setup.py) egg_info for package pexpect Traceback (most recent call last): File "", line 17, in File "c:\users\saint\appdata\local\temp\pip_build_Saint\pexpect\setup.py", line 3, in from pexpect import __version__ File "pexpect\__init__.py", line 89, in support it. Pexpect is intended for UNIX-like operating systems.''') ImportError: No module named resource A critical module was not found. Probably this operating system does not support it. Pexpect is intended for UNIX-like operating systems. Complete output from command python setup.py egg_info: Traceback (most recent call last): File "", line 17, in File "c:\users\saint\appdata\local\temp\pip_build_Saint\pexpect\setup.py", line 3, in from pexpect import __version__ File "pexpect\__init__.py", line 89, in support it. Pexpect is intended for UNIX-like operating systems.''') ImportError: No module named resource A critical module was not found. Probably this operating system does not support it. Pexpect is intended for UNIX-like operating systems. ---------------------------------------- Cleaning up... Command python setup.py egg_info failed with error code 1 in c:\users\saint\appdata\local\temp\pip_build_Saint\pexpect Storing debug log for failure in C:\Users\Saint\pip\pip.log ``` -------------------------------- ### Creating an Agent from Another Agent's Behaviour Source: https://github.com/javipalanca/spade/blob/master/docs/usage.md Illustrates how to instantiate and start a new agent from within the behavior of an existing agent. Ensure to await the agent's start method. ```python import spade from spade.agent import Agent from spade.behaviour import OneShotBehaviour class AgentExample(Agent): async def setup(self): print(f"{self.jid} created.") class CreateBehav(OneShotBehaviour): async def run(self): agent2 = AgentExample("agent2_example@your_xmpp_server", "fake_password") await agent2.start(auto_register=True) async def main(): agent1 = AgentExample("agent1_example@your_xmpp_server", "fake_password") behav = CreateBehav() agent1.add_behaviour(behav) await agent1.start(auto_register=True) # wait until the behaviour is finished to quit spade. await behav.join() if __name__ == "__main__": spade.run(main()) ``` -------------------------------- ### Start Default Web Interface Source: https://github.com/javipalanca/spade/blob/master/docs/web.md Starts the default web interface for an agent. Ensure you replace placeholder JIDs and passwords with your actual credentials. ```python agent = MyAgent("your_jid@your_xmpp_server", "your_password") await agent.start() agent.web.start(hostname="127.0.0.1", port="10000") ``` -------------------------------- ### Install SPADE from source with pip Source: https://github.com/javipalanca/spade/blob/master/docs/installation.md Install SPADE from the local source code using pip in editable mode. This is the traditional method for installing from source. ```bash $ pip install -e . ``` -------------------------------- ### SPADE installation success output Source: https://github.com/javipalanca/spade/wiki/Installation-on-Windows-8.1-with-python-2.7.9-64-bit This output indicates a successful installation of SPADE after resolving dependency issues, such as installing pywin32. ```text python setup.py install running install running bdist_egg running egg_info writing requirements to SPADE.egg-info\requires.txt writing SPADE.egg-info\PKG-INFO writing top-level names to SPADE.egg-info\top_level.txt writing dependency_links to SPADE.egg-info\dependency_links.txt package init file 'xmppd\socker\__init__.py' not found (or not a regular file) reading manifest file 'SPADE.egg-info\SOURCES.txt' reading manifest template 'MANIFEST.in' writing manifest file 'SPADE.egg-info\SOURCES.txt' installing library code to build\bdist.win-amd64\egg running install_lib running build_py running build_ext creating build\bdist.win-amd64\egg creating build\bdist.win-amd64\egg\spade ``` -------------------------------- ### Install SPADE using pip Source: https://github.com/javipalanca/spade/wiki/Home Install the SPADE library using the pip package manager. This is the recommended method for most users. ```bash pip install SPADE ``` -------------------------------- ### Template Example Source: https://github.com/javipalanca/spade/blob/master/docs/web.md A simple Jinja2 template demonstrating variable substitution, loops, and agent data access. ```html {{ agent.jid }} My favourite number is {{ number }}

My behaviours:

    {% for b in behaviours %}
  1. {{ b }}
  2. {% endfor %}
``` -------------------------------- ### Install Development Dependencies with pip Source: https://github.com/javipalanca/spade/blob/master/CONTRIBUTING.rst Install the project and its development dependencies using traditional pip and virtualenv tools. ```shell mkvirtualenv spade cd spade/ pip install -e .[dev] ``` -------------------------------- ### Install SPADE globally with uv Source: https://github.com/javipalanca/spade/blob/master/docs/installation.md Install SPADE globally using uv's pip interface if you prefer not to manage a specific project environment. ```bash $ uv pip install spade ``` -------------------------------- ### Basic Controller Example Source: https://github.com/javipalanca/spade/blob/master/docs/web.md A basic controller that retrieves agent behaviors and a random number to pass to a template. ```python async def my_behaviours_controller(request): behaviours_list = [] for b in self.agent.behaviours: behaviours_list.append(str(b)) return { "behaviours": behaviours_list, "rand": random.random() } ``` -------------------------------- ### Template Matching Example Source: https://github.com/javipalanca/spade/blob/master/docs/agents.md Demonstrates how to create a Template instance and match it against a Message. Ensure all attributes in the template match the message for a successful match. ```python template = Template() template.sender = "sender1@host" template.to = "recv1@host" template.body = "Hello World" template.thread = "thread-id" template.metadata = {"performative": "query"} message = Message() message.sender = "sender1@host" message.to = "recv1@host" message.body = "Hello World" message.thread = "thread-id" message.set_metadata("performative", "query") assert template.match(message) ``` -------------------------------- ### Install SPADE with development extras using pip Source: https://github.com/javipalanca/spade/blob/master/docs/installation.md Install SPADE and its development dependencies from the local source code using pip. This includes extra packages required for development. ```bash $ pip install -e .[dev] ``` -------------------------------- ### Periodic Behaviour Example Source: https://github.com/javipalanca/spade/blob/master/docs/behaviours.md This example demonstrates a PeriodicBehaviour that sends messages at a set interval with an optional startup delay. It also includes a CyclicBehaviour to receive messages. Remember to replace placeholder JIDs and passwords with your own. ```python import datetime import getpass import spade from spade.agent import Agent from spade.behaviour import CyclicBehaviour, PeriodicBehaviour from spade.message import Message class PeriodicSenderAgent(Agent): class InformBehav(PeriodicBehaviour): async def run(self): print(f"PeriodicSenderBehaviour running at {datetime.datetime.now().time()}: {self.counter}") msg = Message(to=self.get("receiver_jid")) # Instantiate the message msg.body = "Hello World" # Set the message content await self.send(msg) print("Message sent!") if self.counter == 5: self.kill() self.counter += 1 async def on_end(self): # stop agent from behaviour await self.agent.stop() async def on_start(self): self.counter = 0 async def setup(self): print(f"PeriodicSenderAgent started at {datetime.datetime.now().time()}") start_at = datetime.datetime.now() + datetime.timedelta(seconds=5) b = self.InformBehav(period=2, start_at=start_at) self.add_behaviour(b) class ReceiverAgent(Agent): class RecvBehav(CyclicBehaviour): async def run(self): print("RecvBehav running") msg = await self.receive(timeout=10) # wait for a message for 10 seconds if msg: print("Message received with content: {}".format(msg.body)) else: print("Did not received any message after 10 seconds") self.kill() async def on_end(self): await self.agent.stop() async def setup(self): print("ReceiverAgent started") b = self.RecvBehav() self.add_behaviour(b) async def main(): receiver_jid = input("Receiver JID> ") passwd = getpass.getpass() receiveragent = ReceiverAgent(receiver_jid, passwd) sender_jid = input("Sender JID> ") passwd = getpass.getpass() senderagent = PeriodicSenderAgent(sender_jid, passwd) await receiveragent.start(auto_register=True) senderagent.set("receiver_jid", receiver_jid) # store receiver_jid in the sender knowledge base await senderagent.start(auto_register=True) await spade.wait_until_finished(receiveragent) await senderagent.stop() await receiveragent.stop() print("Agents finished") if __name__ == "__main__": spade.run(main()) ``` -------------------------------- ### Sync dependencies from source with uv Source: https://github.com/javipalanca/spade/blob/master/docs/installation.md Install SPADE and its dependencies from the local source code using uv. This is the recommended method after cloning the repository. ```bash $ uv sync ``` -------------------------------- ### Add Menu Entry Source: https://github.com/javipalanca/spade/blob/master/docs/web.md Example of how to add a new entry to the agent's web interface menu bar. ```python agent.web.add_menu_entry("My entry", "/my_entry", "fa fa-user") ``` -------------------------------- ### Example P2P Mixin Implementation Source: https://github.com/javipalanca/spade/blob/master/docs/extending.md Implement a mixin class that extends core functionalities. This example shows a `P2PMixin` that conditionally calls a `send_p2p` method or the parent's `send` method based on a `p2p` flag. ```python class P2PMixin(object): async def send(self, msg, p2p=False): if p2p: await self.send_p2p(msg) else: await super().send(msg) async def send_p2p(self, msg): ... ``` -------------------------------- ### Sync dependencies with development extras using uv Source: https://github.com/javipalanca/spade/blob/master/docs/installation.md Install SPADE and its development dependencies from the local source code using uv. Use this for development purposes. ```bash $ uv sync --extra dev ``` -------------------------------- ### SPADE Sender and Receiver Agents Example Source: https://github.com/javipalanca/spade/blob/master/docs/agents.md This example demonstrates a complete communication loop where a sender agent sends a message and a receiver agent with a matching template receives it. Both agents stop after their respective behaviors complete. ```python import spade from spade.agent import Agent from spade.behaviour import OneShotBehaviour from spade.message import Message from spade.template import Template class SenderAgent(Agent): class InformBehav(OneShotBehaviour): async def run(self): print("InformBehav running") msg = Message(to="receiver@your_xmpp_server") # Instantiate the message msg.set_metadata("performative", "inform") # Set the "inform" FIPA performative msg.body = "Hello World" # Set the message content await self.send(msg) print("Message sent!") # stop agent from behaviour await self.agent.stop() async def setup(self): print("SenderAgent started") b = self.InformBehav() self.add_behaviour(b) class ReceiverAgent(Agent): class RecvBehav(OneShotBehaviour): async def run(self): print("RecvBehav running") msg = await self.receive(timeout=10) # wait for a message for 10 seconds if msg: print("Message received with content: {}".format(msg.body)) else: print("Did not received any message after 10 seconds") # stop agent from behaviour await self.agent.stop() async def setup(self): print("ReceiverAgent started") b = self.RecvBehav() template = Template() template.set_metadata("performative", "inform") self.add_behaviour(b, template) async def main(): receiveragent = ReceiverAgent("receiver@your_xmpp_server", "receiver_password") await receiveragent.start(auto_register=True) print("Receiver started") senderagent = SenderAgent("sender@your_xmpp_server", "sender_password") await senderagent.start(auto_register=True) print("Sender started") await spade.wait_until_finished(receiveragent) print("Agents finished") if __name__ == "__main__": spade.run(main()) ``` -------------------------------- ### Spade Presence Module Example Source: https://github.com/javipalanca/spade/blob/master/docs/presence.md This code demonstrates setting agent presence, subscribing to other agents, and handling presence events. It requires the spade library and asyncio. Ensure agents are configured with valid JIDs and passwords. ```python import getpass import asyncio import spade from spade.agent import Agent from spade.behaviour import OneShotBehaviour from spade.presence import PresenceType, PresenceShow, PresenceInfo class Agent1(Agent): async def setup(self): print(f"Agent {self.name} running") self.add_behaviour(self.Behav1()) class Behav1(OneShotBehaviour): def on_available(self, peer_jid, presence_info, last_presence): print(f"[{self.agent.name}] Agent {peer_jid.split('@')[0]} is {presence_info.show.value}") def on_subscribed(self, peer_jid): print(f"[{self.agent.name}] Agent {peer_jid.split('@')[0]} has accepted the subscription") contacts = self.agent.presence.get_contacts() print(f"[{self.agent.name}] Contacts List: {contacts}") def on_subscribe(self, peer_jid): print(f"[{self.agent.name}] Agent {peer_jid.split('@')[0]} asked for subscription. Let's approve it") self.presence.approve_subscription(peer_jid) async def run(self): self.presence.on_subscribe = self.on_subscribe self.presence.on_subscribed = self.on_subscribed self.presence.on_available = self.on_available self.presence.set_presence( presence_type=PresenceType.AVAILABLE, show=PresenceShow.CHAT, status="Ready to chat" ) self.presence.subscribe(self.agent.jid2) class Agent2(Agent): async def setup(self): print(f"Agent {self.name} running") self.add_behaviour(self.Behav2()) class Behav2(OneShotBehaviour): def on_available(self, peer_jid, presence_info, last_presence): print(f"[{self.agent.name}] Agent {peer_jid.split('@')[0]} is {presence_info.show.value}") def on_subscribed(self, peer_jid): print(f"[{self.agent.name}] Agent {peer_jid.split('@')[0]} has accepted the subscription") contacts = self.agent.presence.get_contacts() print(f"[{self.agent.name}] Contacts List: {contacts}") def on_subscribe(self, peer_jid): print(f"[{self.agent.name}] Agent {peer_jid.split('@')[0]} asked for subscription. Let's approve it") self.presence.approve_subscription(peer_jid) self.presence.subscribe(peer_jid) async def run(self): self.presence.set_presence( presence_type=PresenceType.AVAILABLE, show=PresenceShow.CHAT, status="Ready to chat" ) self.presence.on_subscribe = self.on_subscribe self.presence.on_subscribed = self.on_subscribed self.presence.on_available = self.on_available async def main(): jid1 = input("Agent1 JID> ") passwd1 = getpass.getpass() jid2 = input("Agent2 JID> ") passwd2 = getpass.getpass() agent2 = Agent2(jid2, passwd2) agent1 = Agent1(jid1, passwd1) agent1.jid2 = jid2 agent2.jid1 = jid1 await agent2.start() await agent1.start() while True: try: await asyncio.sleep(1) except KeyboardInterrupt: break await agent1.stop() await agent2.stop() if __name__ == "__main__": spade.run(main()) ``` -------------------------------- ### Get Agent Presence Information Source: https://github.com/javipalanca/spade/blob/master/docs/presence.md Retrieves the agent's current presence information, checks availability, and gets the current show state. ```python presence_info = agent.presence.get_presence() # Gets your current presence information ``` ```python agent.presence.is_available() # Returns a boolean to report whether the agent is available or not ``` ```python current_show = agent.presence.get_show() # Gets your current PresenceShow info ``` -------------------------------- ### Create a Basic SPADE Agent Source: https://github.com/javipalanca/spade/blob/master/docs/usage.md This snippet demonstrates how to create a simple SPADE agent that prints a message upon setup. Ensure you replace placeholder JIDs and passwords with your actual account details. ```python import spade class DummyAgent(spade.agent.Agent): async def setup(self): print("Hello World! I'm agent {}".format(str(self.jid))) async def main(): dummy = DummyAgent("dummy@localhost", "your_password") await dummy.start() if __name__ == "__main__": spade.run(main()) ``` -------------------------------- ### Clone SPADE from GitHub Source: https://github.com/javipalanca/spade/blob/master/docs/installation.md Download the SPADE source code by cloning the public Git repository. This is the first step for installing from source. ```bash $ git clone git://github.com/javipalanca/spade ``` -------------------------------- ### Output for Behaviour Termination Example Source: https://github.com/javipalanca/spade/blob/master/docs/usage.md Shows the console output when the agent's behavior is terminated after reaching a specific counter value. ```text $ python killbehav.py Agent starting . . Starting behaviour . . Counter: 0 Counter: 1 Counter: 2 Counter: 3 Behaviour finished with exit code 10. ``` -------------------------------- ### Agent Execution Output Example Source: https://github.com/javipalanca/spade/blob/master/docs/usage.md This shows the typical console output when running a SPADE agent that counts indefinitely until interrupted. ```text $ python dummyagent.py Agent starting . . DummyAgent started. Check its console to see the output. Wait until user interrupts with ctrl+C Starting behaviour . . Counter: 0 Counter: 1 Counter: 2 Counter: 3 Counter: 4 Counter: 5 Counter: 6 Counter: 7 ``` -------------------------------- ### SPADE Sender Agent Output Source: https://github.com/javipalanca/spade/blob/master/docs/agents.md This is the expected console output when running the sender agent example script. ```bash $ python sender.py SenderAgent started InformBehav running Message sent! Agent finished with exit code: Job Finished! ``` -------------------------------- ### Launch SPADE XMPP Server via CLI Source: https://github.com/javipalanca/spade/blob/master/docs/usage.md Start an independent SPADE XMPP server using the 'spade run' command. This is useful for complex MAS integrations and detailed message logging. ```bash $ spade run ╭─────────────────────────────── SPADE ────────────────────────────────╮ │ SPADE - Smart Python Agent Development Environment │ │ │ │ Development Lead: │ - Javi Palanca │ │ Funded by: │ - Valencian Research Institute for Artificial Intelligence (VRAIN) │ │ URL: │ - https://spadeagents.eu │ │ Documentation: │ - https://spadeagents.eu/docs/spade/ │ ╰────────────────── Version: 4.1.4 License: MIT ──────────────────╯ yyyy-m-d h:m:s | INFO | pyjabber.server:run_server:89 - Starting server... yyyy-m-d h:m:s | INFO | pyjabber.server:run_server:133 - Client domain => 0.0.0.0 yyyy-m-d h:m:s | INFO | pyjabber.server:run_server:134 - Server is listening clients on [('0.0.0.0', 5222), ('158.42.184.157', 5222)] yyyy-m-d h:m:s | INFO | pyjabber.server:run_server:149 - Server is listening servers on [('0.0.0.0', 5269)] yyyy-m-d h:m:s | INFO | pyjabber.server:run_server:150 - Server started... yyyy-m-d h:m:s | INFO | pyjabber.webpage.adminPage:start:35 - Serving admin webpage on http://localhost:9090 ``` -------------------------------- ### Create a SPADE Agent with a Cyclic Behavior Source: https://github.com/javipalanca/spade/blob/master/docs/usage.md This example shows how to create a SPADE agent with a cyclic behavior that increments a counter every second. Remember to update the agent's JID and password. ```python import asyncio import spade from spade import wait_until_finished from spade.agent import Agent from spade.behaviour import CyclicBehaviour class DummyAgent(Agent): class MyBehav(CyclicBehaviour): async def on_start(self): print("Starting behaviour . . .") self.counter = 0 async def run(self): print("Counter: {}".format(self.counter)) self.counter += 1 await asyncio.sleep(1) async def setup(self): print("Agent starting . . .") b = self.MyBehav() self.add_behaviour(b) async def main(): dummy = DummyAgent("dummy@localhost", "your_password") await dummy.start() print("DummyAgent started. Check its console to see the output.") print("Wait until user interrupts with ctrl+C") await wait_until_finished(dummy) if __name__ == "__main__": spade.run(main()) ``` -------------------------------- ### SPADE Sender and Receiver Agents Output Source: https://github.com/javipalanca/spade/blob/master/docs/agents.md This is the expected console output when running the combined sender and receiver agent example script. ```bash $ python send_and_recv.py ReceiverAgent started Receiver started RecvBehav running SenderAgent started Sender started InformBehav running Message sent! Message received with content: Hello World Agents finished Process finished with exit code 0 ``` -------------------------------- ### Setting Visual Studio environment variables Source: https://github.com/javipalanca/spade/wiki/Installation-on-Windows-8.1-with-python-2.7.9-64-bit These commands set environment variables to point to the correct Visual Studio installation, which is necessary for the build process on Windows. ```batch SET VS100COMNTOOLS=%VS120COMNTOOLS% SET VS90COMNTOOLS=%VS120COMNTOOLS% ``` -------------------------------- ### Simple FSM Behaviour Example Source: https://github.com/javipalanca/spade/blob/master/docs/behaviours.md Defines a simple FSM with three states, demonstrating state transitions, sending messages to itself, and handling messages in a final state. This is useful for sequential processes where states need to communicate. ```python import spade from spade.agent import Agent from spade.behaviour import FSMBehaviour, State from spade.message import Message STATE_ONE = "STATE_ONE" STATE_TWO = "STATE_TWO" STATE_THREE = "STATE_THREE" class ExampleFSMBehaviour(FSMBehaviour): async def on_start(self): print(f"FSM starting at initial state {self.current_state}") async def on_end(self): print(f"FSM finished at state {self.current_state}") await self.agent.stop() class StateOne(State): async def run(self): print("I'm at state one (initial state)") msg = Message(to=str(self.agent.jid)) msg.body = "msg_from_state_one_to_state_three" await self.send(msg) self.set_next_state(STATE_TWO) class StateTwo(State): async def run(self): print("I'm at state two") self.set_next_state(STATE_THREE) class StateThree(State): async def run(self): print("I'm at state three (final state)") msg = await self.receive(timeout=5) print(f"State Three received message {msg.body}") # no final state is set, since this is a final state class FSMAgent(Agent): async def setup(self): fsm = ExampleFSMBehaviour() fsm.add_state(name=STATE_ONE, state=StateOne(), initial=True) fsm.add_state(name=STATE_TWO, state=StateTwo()) fsm.add_state(name=STATE_THREE, state=StateThree()) fsm.add_transition(source=STATE_ONE, dest=STATE_TWO) fsm.add_transition(source=STATE_TWO, dest=STATE_THREE) self.add_behaviour(fsm) async def main(): fsmagent = FSMAgent("fsmagent@your_xmpp_server", "your_password") await fsmagent.start() await spade.wait_until_finished(fsmagent) await fsmagent.stop() print("Agent finished") if __name__ == "__main__": spade.run(main()) ``` -------------------------------- ### TimeoutBehaviour Example Source: https://github.com/javipalanca/spade/blob/master/docs/behaviours.md Demonstrates a TimeoutBehaviour that sends a message after a specified delay. The receiver agent uses a CyclicBehaviour to listen for messages. ```default import getpass import datetime import spade from spade.agent import Agent from spade.behaviour import CyclicBehaviour, TimeoutBehaviour from spade.message import Message class TimeoutSenderAgent(Agent): class InformBehav(TimeoutBehaviour): async def run(self): print(f"TimeoutSenderBehaviour running at {datetime.datetime.now().time()}") msg = Message(to=self.get("receiver_jid")) # Instantiate the message msg.body = "Hello World" # Set the message content await self.send(msg) async def on_end(self): await self.agent.stop() async def setup(self): print(f"TimeoutSenderAgent started at {datetime.datetime.now().time()}") start_at = datetime.datetime.now() + datetime.timedelta(seconds=5) b = self.InformBehav(start_at=start_at) self.add_behaviour(b) class ReceiverAgent(Agent): class RecvBehav(CyclicBehaviour): async def run(self): msg = await self.receive(timeout=10) # wait for a message for 10 seconds if msg: print("Message received with content: {}".format(msg.body)) else: print("Did not received any message after 10 seconds") self.kill() async def on_end(self): await self.agent.stop() async def setup(self): b = self.RecvBehav() self.add_behaviour(b) async def main(): receiver_jid = input("Receiver JID> ") passwd = getpass.getpass() receiveragent = ReceiverAgent(receiver_jid, passwd) sender_jid = input("Sender JID> ") passwd = getpass.getpass() senderagent = TimeoutSenderAgent(sender_jid, passwd) await receiveragent.start(auto_register=True) senderagent.set("receiver_jid", receiver_jid) # store receiver_jid in the sender knowledge base await senderagent.start(auto_register=True) await spade.wait_until_finished(receiveragent) await senderagent.stop() await receiveragent.stop() print("Agents finished") if __name__ == "__main__": spade.run(main()) ``` -------------------------------- ### Create Custom Web Interface with Controller Source: https://github.com/javipalanca/spade/blob/master/docs/web.md Registers a custom GET endpoint with a controller and template. The controller is an async function that prepares data for the template. Ensure you do not use the /spade path to avoid conflicts. ```python async def hello_controller(request): return {"number": 42} a = Agent("your_jid@your_xmpp_server", "your_password") a.web.add_get("/hello", hello_controller, "hello.html") await a.start(auto_register=True) a.web.start(port=10000) ``` -------------------------------- ### Waiting for a Behaviour to Finish Source: https://github.com/javipalanca/spade/blob/master/docs/behaviours.md Demonstrates how to use the `join` method to block execution until a specific behaviour completes. This is useful for coordinating agent tasks where one task must finish before another can start. Note that `join` is a blocking operation. ```python import asyncio import getpass import spade from spade.agent import Agent from spade.behaviour import OneShotBehaviour class DummyAgent(Agent): class LongBehav(OneShotBehaviour): async def run(self): await asyncio.sleep(5) print("Long Behaviour has finished") class WaitingBehav(OneShotBehaviour): async def run(self): await self.agent.behav.join() # this join must be awaited print("Waiting Behaviour has finished") async def setup(self): print("Agent starting . . .") self.behav = self.LongBehav() self.add_behaviour(self.behav) self.behav2 = self.WaitingBehav() self.add_behaviour(self.behav2) async def main(): jid = input("JID> ") passwd = getpass.getpass() dummy = DummyAgent(jid, passwd) await dummy.start() await dummy.behav2.join() print("Stopping agent.") await dummy.stop() if __name__ == "__main__": spade.run(main()) ``` -------------------------------- ### SPADE Sender Agent Example Source: https://github.com/javipalanca/spade/blob/master/docs/agents.md This agent sends an 'inform' message with custom metadata and body to a receiver agent. It stops after sending the message. ```python import spade from spade.agent import Agent from spade.behaviour import OneShotBehaviour from spade.message import Message from spade.template import Template class SenderAgent(Agent): class InformBehav(OneShotBehaviour): async def run(self): print("InformBehav running") msg = Message(to="receiver@your_xmpp_server") # Instantiate the message msg.set_metadata("performative", "inform") # Set the "inform" FIPA performative msg.set_metadata("ontology", "myOntology") # Set the ontology of the message content msg.set_metadata("language", "OWL-S") # Set the language of the message content msg.body = "Hello World" # Set the message content await self.send(msg) print("Message sent!") # set exit_code for the behaviour self.exit_code = "Job Finished!" # stop agent from behaviour await self.agent.stop() async def setup(self): print("SenderAgent started") self.b = self.InformBehav() self.add_behaviour(self.b) async def main(): senderagent = Agent("sender@your_xmpp_server", "sender_password") await senderagent.start(auto_register=True) print("Sender started") # The receiveragent is not defined in this snippet, but is expected to be running for spade.wait_until_finished # await spade.wait_until_finished(receiveragent) print("Agents finished") if __name__ == "__main__": spade.run(main()) ``` -------------------------------- ### Example Custom Behavior Class Source: https://github.com/javipalanca/spade/blob/master/docs/extending.md Define a new behavior by inheriting from `spade.behaviour.PeriodicBehaviour` and overriding methods like `_step` and `done`. Avoid overriding user-reserved methods like `on_start`, `run`, and `on_end`. ```python class BDIBehaviour(spade.behaviour.PeriodicBehaviour): async def _step(self): # the bdi stuff def add_belief(self, ...): ... def add_desire(self, ...): ... def add_intention(self, ...): ... def done(self): # the done evaluation ... ``` -------------------------------- ### Initialize a new uv project Source: https://github.com/javipalanca/spade/blob/master/docs/installation.md Create a new project managed by uv. This is the recommended first step for new projects. ```bash $ uv init spade-demo $ cd spade-demo ``` -------------------------------- ### Handle Subscription Requests Source: https://github.com/javipalanca/spade/blob/master/docs/presence.md Sets up a callback function to handle incoming subscription requests. The handler can then approve or deny the request. ```python def my_on_subscribe_callback(peer_jid): if i_want_to_approve_request: self.presence.approve_subscription(peer_jid) agent.presence.on_subscribe = my_on_subscribe_callback ``` -------------------------------- ### Get Agent Status Source: https://github.com/javipalanca/spade/blob/master/docs/presence.md Retrieves the textual status message associated with the agent's presence. ```python agent.presence.get_status() ``` -------------------------------- ### Get Specific Contact Source: https://github.com/javipalanca/spade/blob/master/docs/presence.md Retrieves a single contact by their JID. Returns a Contact object if found, otherwise behavior is undefined. ```python contact = agent.presence.get_contact("friend@server.com") ``` -------------------------------- ### Get All Contacts Source: https://github.com/javipalanca/spade/blob/master/docs/presence.md Retrieves a dictionary of all subscribed contacts. Keys are JIDs and values are Contact objects containing presence and other information. ```python >>> contacts = agent.presence.get_contacts() >>> contacts[myfriend_jid] Contact( JID: my_friend@server.com, Name: My Friend, Presence: PresenceInfo(Type: PresenceType.AVAILABLE, Show: PresenceShow.CHAT, Status: "Working", Priority: 10) ) ``` -------------------------------- ### Lint and Format Code with uv Source: https://github.com/javipalanca/spade/blob/master/CONTRIBUTING.rst Check code style and formatting using ruff with uv. ```shell uv run ruff check spade tests uv run ruff format --check spade tests ``` -------------------------------- ### Integrating OWL Content Language Source: https://github.com/javipalanca/spade/blob/master/docs/extending.md This snippet demonstrates how to create a library to handle OWL content. It shows parsing incoming OWL messages and preparing OWL replies. ```python from spade_owl import parse as owl_parse from spade_owl import dump as owl_dump class MyBehaviour(spade.behaviour.CyclicBehaviour): async def run(self): msg = await self.receive() owl_content = owl_parse(msg.content) # do wat you want with the owl content reply.content = owl_dump(...my owl reply...) await self.send(reply) ``` -------------------------------- ### Agent Stopping Alert Source: https://github.com/javipalanca/spade/blob/master/spade/templates/internal_tpl_base.html This JavaScript code is used to trigger an alert when the agent is stopping. It sends a GET request to the '/spade/stop/now/' endpoint. ```javascript var xhr = new XMLHttpRequest(); xhr.open("GET", "/spade/stop/now/", true); xhr.send(null); ``` -------------------------------- ### Lint and Format Code with pip Source: https://github.com/javipalanca/spade/blob/master/CONTRIBUTING.rst Check code style and formatting using ruff with traditional tools. ```shell ruff check spade tests ruff format --check spade tests ``` -------------------------------- ### Add SPADE to uv project dependencies Source: https://github.com/javipalanca/spade/blob/master/docs/installation.md Add the SPADE package to your project's dependencies using uv. This ensures SPADE is installed within your project's environment. ```bash $ uv add spade ``` -------------------------------- ### Clone Spade Repository Source: https://github.com/javipalanca/spade/blob/master/CONTRIBUTING.rst Clone your fork of the Spade repository locally to begin development. ```shell git clone git@github.com:your_name_here/spade.git ``` -------------------------------- ### Upload and Send File Separately with Spade Source: https://github.com/javipalanca/spade/blob/master/docs/agents.md Shows how to upload a file first using `upload_file` and then send its URL using `send_file` for more customized behaviors. ```python class UploadAndSendBehaviour(OneShotBehaviour): async def run(self): with open("text.txt", "rb") as file: url = await self.upload_file(filename="test.txt", input_file=file) await self.send_file(to="receiver@localhost", url=url) class ReceiveFileBehaviour(CyclicBehaviour): async def run(self): msg = self.receive(5) if msg: url = msg.get_metadata("url") if url: await self.download_file(url, "path/to/download") receive_template = Template() receive_template.set_metadata("performative", "0363") sharer = Agent("uploader@localhost", "1234") sharer.add_behaviour(UploadAndSendBehaviour()) receiver = Agent("receiver@localhost", "1234") receiver.add_behaviour(ReceiveFileBehaviour(), receive_template) ``` -------------------------------- ### Send and Receive File with Spade Source: https://github.com/javipalanca/spade/blob/master/docs/agents.md Demonstrates the sender behavior using `upload_and_send_file` and the receiver behavior listening for file messages. ```python class SharerBehaviour(OneShotBehaviour): async def run(self): with open("text.txt", "rb") as file: url = await self.upload_and_send_file( to="receiver@localhost", filename="test.txt", input_file=file ) class ReceiveFileBehaviour(CyclicBehaviour): async def run(self): msg = self.receive(5) if msg: url = msg.get_metadata("url") if url: await self.download_file(url, "path/to/download") receive_template = Template() receive_template.set_metadata("performative", "0363") sharer = Agent("uploader@localhost", "1234") sharer.add_behaviour(SharerBehaviour()) receiver = Agent("receiver@localhost", "1234") receiver.add_behaviour(ReceiveFileBehaviour(), receive_template) ``` -------------------------------- ### Run Tests with uv Source: https://github.com/javipalanca/spade/blob/master/CONTRIBUTING.rst Execute the test suite using pytest and tox with uv. ```shell uv run pytest uv run tox ``` -------------------------------- ### Run Tests with pip Source: https://github.com/javipalanca/spade/blob/master/CONTRIBUTING.rst Execute the test suite using pytest and tox with traditional tools. ```shell pytest tox ``` -------------------------------- ### Commit and Push Changes Source: https://github.com/javipalanca/spade/blob/master/CONTRIBUTING.rst Stage, commit, and push your local changes to your fork on GitHub. ```shell git add . git commit -m "Your detailed description of your changes." git push origin name-of-your-bugfix-or-feature ``` -------------------------------- ### Download SPADE source tarball Source: https://github.com/javipalanca/spade/blob/master/docs/installation.md Download the SPADE source code as a tarball archive directly from GitHub. This is an alternative to cloning the repository. ```bash $ curl -OL https://github.com/javipalanca/spade/tarball/master ``` -------------------------------- ### Set All Presence Attributes Source: https://github.com/javipalanca/spade/blob/master/docs/presence.md Sets all presence attributes simultaneously: type, show, status, and priority. All parameters are optional. ```python agent.presence.set_presence( presence_type=PresenceType.AVAILABLE, # set availability show=PresenceShow.CHAT, # show status status="Lunch", # status message priority=2 # connection priority ) ``` -------------------------------- ### Create a New Branch Source: https://github.com/javipalanca/spade/blob/master/CONTRIBUTING.rst Create a new branch for your bugfix or feature development. ```shell git checkout -b name-of-your-bugfix-or-feature ``` -------------------------------- ### Create a FIPA Message with Fluent Builder Source: https://github.com/javipalanca/spade/blob/master/docs/agents.md Use the FIPAMessageBuilder to construct a FIPA message step-by-step. Specify sender, receiver, performative, body (as JSON), and ontology. ```default from spade.fipa_message import FIPAMessageBuilder msg = ( FIPAMessageBuilder(sender="agent1@localhost", receiver="agent2@localhost") .set_performative("inform") .set_body({"data": "Hello World"}, as_json=True) .set_ontology("example") .build() ) await self.send(msg) ``` -------------------------------- ### Redirect Controller Source: https://github.com/javipalanca/spade/blob/master/docs/web.md Controller that raises an HTTPFound exception to redirect the user to a different URL. ```python from aiohttp import web async def my_redirect_controller(request): raise web.HTTPFound("/") ``` -------------------------------- ### Create a Message Filter Template Source: https://github.com/javipalanca/spade/blob/master/docs/agents.md Use the `Template` class to define filters for incoming messages, such as matching a specific performative. ```default template = Template() template.set_metadata("performative", "inform") ```