Source code for smia.logic.acl_smia_messages_utils
importastimportjsonimportrandomimportstringfromsmia.logic.exceptionsimportRequestDataErrorfromsmia.logic.inter_smia_interactions_utilsimportcheck_received_request_data_structure,_logger# Methods related to agent JIDs# -----------------------------
[docs]asyncdefget_xmpp_server_from_jid(agent_object_jid):""" This method get the XMPP server from the JID of the agent. Args: agent_object_jid: the JID object of the SMIA SPADE agent. Returns: str: XMPP server. """try:returnstr(agent_object_jid.domain)exceptAttributeError:passtry:returnstr(agent_object_jid).split('@')[1]exceptAttributeError:passreturnNone
[docs]asyncdefget_agent_id_from_jid(agent_object_jid):""" This method get the identifier of the agent from the JID of the agent. Args: agent_object_jid: the JID object of the SMIA SPADE agent. Returns: str: XMPP server. """try:returnstr(agent_object_jid.localpart)exceptAttributeError:passtry:returnstr(agent_object_jid).split('@')[0]exceptAttributeError:passreturnNone
[docs]defget_sender_from_acl_msg(acl_msg):""" This method returns the identifier of an agent from an ACL message, considering the suffixes that can be added by the XMPP server. Args: acl_msg (spade.message.Message): ACL message object. Returns: str: identifier of the sender of the message. """if'/'instr(acl_msg.sender):# XMPP server can add a random string to differentiate the agent JIDreturnstr(acl_msg.sender).split('/')[0]else:returnstr(acl_msg.sender)
# Methods related to thread of the ACL messages# ---------------------------------------------
[docs]asyncdefcreate_random_thread(agent_object):""" This method creates a value for the thread of a SPADE-ACL message, using the agent identifier and random string. Args: agent_object (spade.Agent): the SPADE agent object of the SMIA agent. Returns: str: thread value """return(f"{awaitget_agent_id_from_jid(agent_object.jid)}-"f"{''.join(random.choices(string.ascii_letters+string.digits,k=5)).lower()}")
# Methods related to body of the ACL messages# -------------------------------------------
[docs]asyncdefgenerate_json_from_schema(schema:dict,**kwargs)->dict:""" This method generates a valid JSON from a predefined JSON Schema. Args: schema (dict): JSON schema object. **kwargs: attributes along with their values to build the JSON. Returns: dict: valid JSON object regarding the given schema. """required_fields=schema.get("required",[])properties=schema.get("properties",{})json_object={}# Mandatory fieldsforfieldinrequired_fields:iffieldnotinkwargs:raiseValueError(f"Missing required parameter: {field}")ifkwargs[field]isNone:raiseValueError(f"Missing required value for parameter: {field}")json_object[field]=kwargs[field]# Optional fieldsforfieldinproperties:iffieldnotinjson_objectandfieldinkwargsandkwargs[field]isnotNone:json_object[field]=kwargs[field]# Validate final messagetry:awaitcheck_received_request_data_structure(json_object,schema)exceptRequestDataErrorase:_logger.warning('A JSON object cannot be created using the schema. Check the failed code.')returnNonereturnjson_object
[docs]defget_parsed_body_from_acl_msg(acl_msg):""" This method gets the body of an ACL message and returns parsed. Args: acl_msg (spade.message.Message): the ACL message object. Returns: parsed body of the ACL message. """# Let's try with JSONtry:returnjson.loads(acl_msg.body)except(json.JSONDecodeError,TypeError):pass# Now let's try Python literal evaluation, to safely evaluate Python literals (list, tuple, int, etc.))try:returnast.literal_eval(acl_msg.body)except(ValueError,SyntaxError):passreturnacl_msg.body