def test_public_id_from_str_not_matching(self, *mocks): """Test case for from_str method regex not matching.""" with self.assertRaises(ValueError): PublicId.from_str("public_id_str")
from aea.configurations.base import PublicId from aea.connections.base import Connection, ConnectionStates from aea.helpers import file_lock from aea.helpers.base import exception_log_and_reraise from aea.mail.base import Envelope logger = logging.getLogger(__name__) INPUT_FILE_KEY = "input_file" OUTPUT_FILE_KEY = "output_file" DEFAULT_INPUT_FILE_NAME = "./input_file" DEFAULT_OUTPUT_FILE_NAME = "./output_file" SEPARATOR = b"," PUBLIC_ID = PublicId.from_str("fetchai/stub:0.8.0") def _encode(e: Envelope, separator: bytes = SEPARATOR): result = b"" result += e.to.encode("utf-8") result += separator result += e.sender.encode("utf-8") result += separator result += str(e.protocol_id).encode("utf-8") result += separator result += e.message_bytes result += separator return result
# -*- coding: utf-8 -*- # ------------------------------------------------------------------------------ # # Copyright 2018-2019 Fetch.AI Limited # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # # ------------------------------------------------------------------------------ """This module contains the implementation of the simple_seller skill.""" from aea.configurations.base import PublicId PUBLIC_ID = PublicId.from_str("fetchai/simple_seller:0.6.0")
def run(): # Create a private key create_private_key(CosmosCrypto.identifier) # Set up the wallet, identity and (empty) resources wallet = Wallet( private_key_paths={CosmosCrypto.identifier: COSMOS_PRIVATE_KEY_FILE}, connection_private_key_paths={CosmosCrypto.identifier: COSMOS_PRIVATE_KEY_FILE}, ) identity = Identity("my_aea", address=wallet.addresses.get(CosmosCrypto.identifier)) resources = Resources() # specify the default routing for some protocols default_routing = { PublicId.from_str("fetchai/ledger_api:0.1.0"): LedgerConnection.connection_id, PublicId.from_str("fetchai/oef_search:0.3.0"): SOEFConnection.connection_id, } default_connection = SOEFConnection.connection_id # create the AEA my_aea = AEA( identity, wallet, resources, default_connection=default_connection, default_routing=default_routing, ) # Add the default protocol (which is part of the AEA distribution) default_protocol = Protocol.from_dir(os.path.join(AEA_DIR, "protocols", "default")) resources.add_protocol(default_protocol) # Add the signing protocol (which is part of the AEA distribution) signing_protocol = Protocol.from_dir(os.path.join(AEA_DIR, "protocols", "signing")) resources.add_protocol(signing_protocol) # Add the ledger_api protocol ledger_api_protocol = Protocol.from_dir( os.path.join(os.getcwd(), "packages", "fetchai", "protocols", "ledger_api",) ) resources.add_protocol(ledger_api_protocol) # Add the oef_search protocol oef_protocol = Protocol.from_dir( os.path.join(os.getcwd(), "packages", "fetchai", "protocols", "oef_search",) ) resources.add_protocol(oef_protocol) # Add the fipa protocol fipa_protocol = Protocol.from_dir( os.path.join(os.getcwd(), "packages", "fetchai", "protocols", "fipa",) ) resources.add_protocol(fipa_protocol) # Add the LedgerAPI connection configuration = ConnectionConfig(connection_id=LedgerConnection.connection_id) ledger_api_connection = LedgerConnection( configuration=configuration, identity=identity ) resources.add_connection(ledger_api_connection) # Add the P2P connection configuration = ConnectionConfig( connection_id=P2PLibp2pConnection.connection_id, delegate_uri="127.0.0.1:11001", entry_peers=[ENTRY_PEER_ADDRESS], local_uri="127.0.0.1:9001", log_file="libp2p_node.log", public_uri="127.0.0.1:9001", ) p2p_connection = P2PLibp2pConnection( configuration=configuration, identity=identity, crypto_store=wallet.connection_cryptos, ) resources.add_connection(p2p_connection) # Add the SOEF connection configuration = ConnectionConfig( api_key=API_KEY, soef_addr=SOEF_ADDR, soef_port=SOEF_PORT, restricted_to_protocols={PublicId.from_str("fetchai/oef_search:0.3.0")}, connection_id=SOEFConnection.connection_id, delegate_uri="127.0.0.1:11001", entry_peers=[ENTRY_PEER_ADDRESS], local_uri="127.0.0.1:9001", log_file="libp2p_node.log", public_uri="127.0.0.1:9001", ) soef_connection = SOEFConnection(configuration=configuration, identity=identity) resources.add_connection(soef_connection) # Add the error and weather_client skills error_skill = Skill.from_dir( os.path.join(AEA_DIR, "skills", "error"), agent_context=my_aea.context ) weather_skill = Skill.from_dir( os.path.join(ROOT_DIR, "packages", "fetchai", "skills", "weather_client"), agent_context=my_aea.context, ) strategy = cast(Strategy, weather_skill.models.get("strategy")) strategy._is_ledger_tx = False for skill in [error_skill, weather_skill]: resources.add_skill(skill) # Run the AEA try: logger.info("STARTING AEA NOW!") my_aea.start() except KeyboardInterrupt: logger.info("STOPPING AEA NOW!") my_aea.stop()
class OefSearchMessage(Message): """A protocol for interacting with an OEF search service.""" protocol_id = PublicId.from_str("fetchai/oef_search:0.13.0") protocol_specification_id = PublicId.from_str("fetchai/oef_search:0.1.0") AgentsInfo = CustomAgentsInfo Description = CustomDescription OefErrorOperation = CustomOefErrorOperation Query = CustomQuery class Performative(Message.Performative): """Performatives for the oef_search protocol.""" OEF_ERROR = "oef_error" REGISTER_SERVICE = "register_service" SEARCH_RESULT = "search_result" SEARCH_SERVICES = "search_services" SUCCESS = "success" UNREGISTER_SERVICE = "unregister_service" def __str__(self) -> str: """Get the string representation.""" return str(self.value) _performatives = { "oef_error", "register_service", "search_result", "search_services", "success", "unregister_service", } __slots__: Tuple[str, ...] = tuple() class _SlotsCls: __slots__ = ( "agents", "agents_info", "dialogue_reference", "message_id", "oef_error_operation", "performative", "query", "service_description", "target", ) def __init__( self, performative: Performative, dialogue_reference: Tuple[str, str] = ("", ""), message_id: int = 1, target: int = 0, **kwargs: Any, ): """ Initialise an instance of OefSearchMessage. :param message_id: the message id. :param dialogue_reference: the dialogue reference. :param target: the message target. :param performative: the message performative. """ super().__init__( dialogue_reference=dialogue_reference, message_id=message_id, target=target, performative=OefSearchMessage.Performative(performative), **kwargs, ) @property def valid_performatives(self) -> Set[str]: """Get valid performatives.""" return self._performatives @property def dialogue_reference(self) -> Tuple[str, str]: """Get the dialogue_reference of the message.""" enforce(self.is_set("dialogue_reference"), "dialogue_reference is not set.") return cast(Tuple[str, str], self.get("dialogue_reference")) @property def message_id(self) -> int: """Get the message_id of the message.""" enforce(self.is_set("message_id"), "message_id is not set.") return cast(int, self.get("message_id")) @property def performative(self) -> Performative: # type: ignore # noqa: F821 """Get the performative of the message.""" enforce(self.is_set("performative"), "performative is not set.") return cast(OefSearchMessage.Performative, self.get("performative")) @property def target(self) -> int: """Get the target of the message.""" enforce(self.is_set("target"), "target is not set.") return cast(int, self.get("target")) @property def agents(self) -> Tuple[str, ...]: """Get the 'agents' content from the message.""" enforce(self.is_set("agents"), "'agents' content is not set.") return cast(Tuple[str, ...], self.get("agents")) @property def agents_info(self) -> CustomAgentsInfo: """Get the 'agents_info' content from the message.""" enforce(self.is_set("agents_info"), "'agents_info' content is not set.") return cast(CustomAgentsInfo, self.get("agents_info")) @property def oef_error_operation(self) -> CustomOefErrorOperation: """Get the 'oef_error_operation' content from the message.""" enforce( self.is_set("oef_error_operation"), "'oef_error_operation' content is not set.", ) return cast(CustomOefErrorOperation, self.get("oef_error_operation")) @property def query(self) -> CustomQuery: """Get the 'query' content from the message.""" enforce(self.is_set("query"), "'query' content is not set.") return cast(CustomQuery, self.get("query")) @property def service_description(self) -> CustomDescription: """Get the 'service_description' content from the message.""" enforce( self.is_set("service_description"), "'service_description' content is not set.", ) return cast(CustomDescription, self.get("service_description")) def _is_consistent(self) -> bool: """Check that the message follows the oef_search protocol.""" try: enforce( type(self.dialogue_reference) == tuple, "Invalid type for 'dialogue_reference'. Expected 'tuple'. Found '{}'." .format(type(self.dialogue_reference)), ) enforce( type(self.dialogue_reference[0]) == str, "Invalid type for 'dialogue_reference[0]'. Expected 'str'. Found '{}'." .format(type(self.dialogue_reference[0])), ) enforce( type(self.dialogue_reference[1]) == str, "Invalid type for 'dialogue_reference[1]'. Expected 'str'. Found '{}'." .format(type(self.dialogue_reference[1])), ) enforce( type(self.message_id) == int, "Invalid type for 'message_id'. Expected 'int'. Found '{}'.". format(type(self.message_id)), ) enforce( type(self.target) == int, "Invalid type for 'target'. Expected 'int'. Found '{}'.". format(type(self.target)), ) # Light Protocol Rule 2 # Check correct performative enforce( type(self.performative) == OefSearchMessage.Performative, "Invalid 'performative'. Expected either of '{}'. Found '{}'.". format(self.valid_performatives, self.performative), ) # Check correct contents actual_nb_of_contents = len(self._body) - DEFAULT_BODY_SIZE expected_nb_of_contents = 0 if self.performative == OefSearchMessage.Performative.REGISTER_SERVICE: expected_nb_of_contents = 1 enforce( type(self.service_description) == CustomDescription, "Invalid type for content 'service_description'. Expected 'Description'. Found '{}'." .format(type(self.service_description)), ) elif self.performative == OefSearchMessage.Performative.UNREGISTER_SERVICE: expected_nb_of_contents = 1 enforce( type(self.service_description) == CustomDescription, "Invalid type for content 'service_description'. Expected 'Description'. Found '{}'." .format(type(self.service_description)), ) elif self.performative == OefSearchMessage.Performative.SEARCH_SERVICES: expected_nb_of_contents = 1 enforce( type(self.query) == CustomQuery, "Invalid type for content 'query'. Expected 'Query'. Found '{}'." .format(type(self.query)), ) elif self.performative == OefSearchMessage.Performative.SEARCH_RESULT: expected_nb_of_contents = 2 enforce( type(self.agents) == tuple, "Invalid type for content 'agents'. Expected 'tuple'. Found '{}'." .format(type(self.agents)), ) enforce( all(type(element) == str for element in self.agents), "Invalid type for tuple elements in content 'agents'. Expected 'str'.", ) enforce( type(self.agents_info) == CustomAgentsInfo, "Invalid type for content 'agents_info'. Expected 'AgentsInfo'. Found '{}'." .format(type(self.agents_info)), ) elif self.performative == OefSearchMessage.Performative.SUCCESS: expected_nb_of_contents = 1 enforce( type(self.agents_info) == CustomAgentsInfo, "Invalid type for content 'agents_info'. Expected 'AgentsInfo'. Found '{}'." .format(type(self.agents_info)), ) elif self.performative == OefSearchMessage.Performative.OEF_ERROR: expected_nb_of_contents = 1 enforce( type(self.oef_error_operation) == CustomOefErrorOperation, "Invalid type for content 'oef_error_operation'. Expected 'OefErrorOperation'. Found '{}'." .format(type(self.oef_error_operation)), ) # Check correct content count enforce( expected_nb_of_contents == actual_nb_of_contents, "Incorrect number of contents. Expected {}. Found {}".format( expected_nb_of_contents, actual_nb_of_contents), ) # Light Protocol Rule 3 if self.message_id == 1: enforce( self.target == 0, "Invalid 'target'. Expected 0 (because 'message_id' is 1). Found {}." .format(self.target), ) except (AEAEnforceError, ValueError, KeyError) as e: _default_logger.error(str(e)) return False return True
# You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # # ------------------------------------------------------------------------------ """Module to declare constants.""" from aea.configurations.base import DEFAULT_LICENSE as DL from aea.configurations.base import DEFAULT_REGISTRY_PATH as DRP from aea.configurations.base import PublicId from aea.crypto.cosmos import CosmosCrypto from aea.crypto.helpers import COSMOS_PRIVATE_KEY_FILE DEFAULT_CONNECTION = PublicId.from_str("fetchai/stub:0.6.0") DEFAULT_PROTOCOL = PublicId.from_str("fetchai/default:0.3.0") DEFAULT_SKILL = PublicId.from_str("fetchai/error:0.3.0") DEFAULT_LEDGER = CosmosCrypto.identifier DEFAULT_PRIVATE_KEY_FILE = COSMOS_PRIVATE_KEY_FILE DEFAULT_REGISTRY_PATH = DRP DEFAULT_LICENSE = DL SIGNING_PROTOCOL = PublicId.from_str("fetchai/signing:0.1.0") STATE_UPDATE_PROTOCOL = PublicId.from_str("fetchai/state_update:0.1.0") LOCAL_PROTOCOLS = [DEFAULT_PROTOCOL, SIGNING_PROTOCOL, STATE_UPDATE_PROTOCOL]
# -*- coding: utf-8 -*- # ------------------------------------------------------------------------------ # # Copyright 2018-2019 Fetch.AI Limited # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # # ------------------------------------------------------------------------------ """This module contains the implementation of the simple service search skill.""" from aea.configurations.base import PublicId PUBLIC_ID = PublicId.from_str("fetchai/simple_service_search:0.5.0")
WORK_DIR = os.getcwd() NOISE_NODE_SOURCE = str( os.path.join(os.path.abspath(os.path.dirname(__file__)), "noise_node.go")) NOISE_NODE_LOG_FILE = "noise_node.log" NOISE_NODE_ENV_FILE = ".env.noise" NOISE_NODE_CLARGS = [str(os.path.join(WORK_DIR, NOISE_NODE_ENV_FILE))] # type: List[str] NOISE = "noise" PUBLIC_ID = PublicId.from_str("fetchai/p2p_noise:0.2.0") # TOFIX(LR) error: Cannot add child handler, the child watcher does not have a loop attached async def _async_golang_get_deps( src: str, loop: AbstractEventLoop) -> asyncio.subprocess.Process: """ Downloads dependencies of go 'src' file - asynchronous """ cmd = ["go", "get", "-d", "-v", "./..."] try: logger.debug(cmd, loop) proc = await asyncio.create_subprocess_exec(*cmd, cwd=os.path.dirname(src), loop=loop) # nosec
def _add_package_type(package_type: PackageType, public_id_str: str) -> PackageId: return PackageId(package_type, PublicId.from_str(public_id_str))
class TacMessage(Message): """The tac protocol implements the messages an AEA needs to participate in the TAC.""" protocol_id = PublicId.from_str("fetchai/tac:0.10.0") ErrorCode = CustomErrorCode class Performative(Message.Performative): """Performatives for the tac protocol.""" CANCELLED = "cancelled" GAME_DATA = "game_data" REGISTER = "register" TAC_ERROR = "tac_error" TRANSACTION = "transaction" TRANSACTION_CONFIRMATION = "transaction_confirmation" UNREGISTER = "unregister" def __str__(self): """Get the string representation.""" return str(self.value) _performatives = { "cancelled", "game_data", "register", "tac_error", "transaction", "transaction_confirmation", "unregister", } class _SlotsCls: __slots__ = ( "agent_addr_to_name", "agent_name", "amount_by_currency_id", "counterparty_address", "counterparty_signature", "currency_id_to_name", "dialogue_reference", "error_code", "exchange_params_by_currency_id", "fee_by_currency_id", "good_id_to_name", "info", "ledger_id", "message_id", "nonce", "performative", "quantities_by_good_id", "sender_address", "sender_signature", "target", "transaction_id", "utility_params_by_good_id", "version_id", ) def __init__( self, performative: Performative, dialogue_reference: Tuple[str, str] = ("", ""), message_id: int = 1, target: int = 0, **kwargs, ): """ Initialise an instance of TacMessage. :param message_id: the message id. :param dialogue_reference: the dialogue reference. :param target: the message target. :param performative: the message performative. """ super().__init__( dialogue_reference=dialogue_reference, message_id=message_id, target=target, performative=TacMessage.Performative(performative), **kwargs, ) @property def valid_performatives(self) -> Set[str]: """Get valid performatives.""" return self._performatives @property def dialogue_reference(self) -> Tuple[str, str]: """Get the dialogue_reference of the message.""" enforce(self.is_set("dialogue_reference"), "dialogue_reference is not set.") return cast(Tuple[str, str], self.get("dialogue_reference")) @property def message_id(self) -> int: """Get the message_id of the message.""" enforce(self.is_set("message_id"), "message_id is not set.") return cast(int, self.get("message_id")) @property def performative(self) -> Performative: # type: ignore # noqa: F821 """Get the performative of the message.""" enforce(self.is_set("performative"), "performative is not set.") return cast(TacMessage.Performative, self.get("performative")) @property def target(self) -> int: """Get the target of the message.""" enforce(self.is_set("target"), "target is not set.") return cast(int, self.get("target")) @property def agent_addr_to_name(self) -> Dict[str, str]: """Get the 'agent_addr_to_name' content from the message.""" enforce( self.is_set("agent_addr_to_name"), "'agent_addr_to_name' content is not set.", ) return cast(Dict[str, str], self.get("agent_addr_to_name")) @property def agent_name(self) -> str: """Get the 'agent_name' content from the message.""" enforce(self.is_set("agent_name"), "'agent_name' content is not set.") return cast(str, self.get("agent_name")) @property def amount_by_currency_id(self) -> Dict[str, int]: """Get the 'amount_by_currency_id' content from the message.""" enforce( self.is_set("amount_by_currency_id"), "'amount_by_currency_id' content is not set.", ) return cast(Dict[str, int], self.get("amount_by_currency_id")) @property def counterparty_address(self) -> str: """Get the 'counterparty_address' content from the message.""" enforce( self.is_set("counterparty_address"), "'counterparty_address' content is not set.", ) return cast(str, self.get("counterparty_address")) @property def counterparty_signature(self) -> str: """Get the 'counterparty_signature' content from the message.""" enforce( self.is_set("counterparty_signature"), "'counterparty_signature' content is not set.", ) return cast(str, self.get("counterparty_signature")) @property def currency_id_to_name(self) -> Dict[str, str]: """Get the 'currency_id_to_name' content from the message.""" enforce( self.is_set("currency_id_to_name"), "'currency_id_to_name' content is not set.", ) return cast(Dict[str, str], self.get("currency_id_to_name")) @property def error_code(self) -> CustomErrorCode: """Get the 'error_code' content from the message.""" enforce(self.is_set("error_code"), "'error_code' content is not set.") return cast(CustomErrorCode, self.get("error_code")) @property def exchange_params_by_currency_id(self) -> Dict[str, float]: """Get the 'exchange_params_by_currency_id' content from the message.""" enforce( self.is_set("exchange_params_by_currency_id"), "'exchange_params_by_currency_id' content is not set.", ) return cast(Dict[str, float], self.get("exchange_params_by_currency_id")) @property def fee_by_currency_id(self) -> Dict[str, int]: """Get the 'fee_by_currency_id' content from the message.""" enforce( self.is_set("fee_by_currency_id"), "'fee_by_currency_id' content is not set.", ) return cast(Dict[str, int], self.get("fee_by_currency_id")) @property def good_id_to_name(self) -> Dict[str, str]: """Get the 'good_id_to_name' content from the message.""" enforce(self.is_set("good_id_to_name"), "'good_id_to_name' content is not set.") return cast(Dict[str, str], self.get("good_id_to_name")) @property def info(self) -> Optional[Dict[str, str]]: """Get the 'info' content from the message.""" return cast(Optional[Dict[str, str]], self.get("info")) @property def ledger_id(self) -> str: """Get the 'ledger_id' content from the message.""" enforce(self.is_set("ledger_id"), "'ledger_id' content is not set.") return cast(str, self.get("ledger_id")) @property def nonce(self) -> str: """Get the 'nonce' content from the message.""" enforce(self.is_set("nonce"), "'nonce' content is not set.") return cast(str, self.get("nonce")) @property def quantities_by_good_id(self) -> Dict[str, int]: """Get the 'quantities_by_good_id' content from the message.""" enforce( self.is_set("quantities_by_good_id"), "'quantities_by_good_id' content is not set.", ) return cast(Dict[str, int], self.get("quantities_by_good_id")) @property def sender_address(self) -> str: """Get the 'sender_address' content from the message.""" enforce(self.is_set("sender_address"), "'sender_address' content is not set.") return cast(str, self.get("sender_address")) @property def sender_signature(self) -> str: """Get the 'sender_signature' content from the message.""" enforce( self.is_set("sender_signature"), "'sender_signature' content is not set." ) return cast(str, self.get("sender_signature")) @property def transaction_id(self) -> str: """Get the 'transaction_id' content from the message.""" enforce(self.is_set("transaction_id"), "'transaction_id' content is not set.") return cast(str, self.get("transaction_id")) @property def utility_params_by_good_id(self) -> Dict[str, float]: """Get the 'utility_params_by_good_id' content from the message.""" enforce( self.is_set("utility_params_by_good_id"), "'utility_params_by_good_id' content is not set.", ) return cast(Dict[str, float], self.get("utility_params_by_good_id")) @property def version_id(self) -> str: """Get the 'version_id' content from the message.""" enforce(self.is_set("version_id"), "'version_id' content is not set.") return cast(str, self.get("version_id")) def _is_consistent(self) -> bool: """Check that the message follows the tac protocol.""" try: enforce( type(self.dialogue_reference) == tuple, "Invalid type for 'dialogue_reference'. Expected 'tuple'. Found '{}'.".format( type(self.dialogue_reference) ), ) enforce( type(self.dialogue_reference[0]) == str, "Invalid type for 'dialogue_reference[0]'. Expected 'str'. Found '{}'.".format( type(self.dialogue_reference[0]) ), ) enforce( type(self.dialogue_reference[1]) == str, "Invalid type for 'dialogue_reference[1]'. Expected 'str'. Found '{}'.".format( type(self.dialogue_reference[1]) ), ) enforce( type(self.message_id) == int, "Invalid type for 'message_id'. Expected 'int'. Found '{}'.".format( type(self.message_id) ), ) enforce( type(self.target) == int, "Invalid type for 'target'. Expected 'int'. Found '{}'.".format( type(self.target) ), ) # Light Protocol Rule 2 # Check correct performative enforce( type(self.performative) == TacMessage.Performative, "Invalid 'performative'. Expected either of '{}'. Found '{}'.".format( self.valid_performatives, self.performative ), ) # Check correct contents actual_nb_of_contents = len(self._body) - DEFAULT_BODY_SIZE expected_nb_of_contents = 0 if self.performative == TacMessage.Performative.REGISTER: expected_nb_of_contents = 1 enforce( type(self.agent_name) == str, "Invalid type for content 'agent_name'. Expected 'str'. Found '{}'.".format( type(self.agent_name) ), ) elif self.performative == TacMessage.Performative.UNREGISTER: expected_nb_of_contents = 0 elif self.performative == TacMessage.Performative.TRANSACTION: expected_nb_of_contents = 10 enforce( type(self.transaction_id) == str, "Invalid type for content 'transaction_id'. Expected 'str'. Found '{}'.".format( type(self.transaction_id) ), ) enforce( type(self.ledger_id) == str, "Invalid type for content 'ledger_id'. Expected 'str'. Found '{}'.".format( type(self.ledger_id) ), ) enforce( type(self.sender_address) == str, "Invalid type for content 'sender_address'. Expected 'str'. Found '{}'.".format( type(self.sender_address) ), ) enforce( type(self.counterparty_address) == str, "Invalid type for content 'counterparty_address'. Expected 'str'. Found '{}'.".format( type(self.counterparty_address) ), ) enforce( type(self.amount_by_currency_id) == dict, "Invalid type for content 'amount_by_currency_id'. Expected 'dict'. Found '{}'.".format( type(self.amount_by_currency_id) ), ) for ( key_of_amount_by_currency_id, value_of_amount_by_currency_id, ) in self.amount_by_currency_id.items(): enforce( type(key_of_amount_by_currency_id) == str, "Invalid type for dictionary keys in content 'amount_by_currency_id'. Expected 'str'. Found '{}'.".format( type(key_of_amount_by_currency_id) ), ) enforce( type(value_of_amount_by_currency_id) == int, "Invalid type for dictionary values in content 'amount_by_currency_id'. Expected 'int'. Found '{}'.".format( type(value_of_amount_by_currency_id) ), ) enforce( type(self.fee_by_currency_id) == dict, "Invalid type for content 'fee_by_currency_id'. Expected 'dict'. Found '{}'.".format( type(self.fee_by_currency_id) ), ) for ( key_of_fee_by_currency_id, value_of_fee_by_currency_id, ) in self.fee_by_currency_id.items(): enforce( type(key_of_fee_by_currency_id) == str, "Invalid type for dictionary keys in content 'fee_by_currency_id'. Expected 'str'. Found '{}'.".format( type(key_of_fee_by_currency_id) ), ) enforce( type(value_of_fee_by_currency_id) == int, "Invalid type for dictionary values in content 'fee_by_currency_id'. Expected 'int'. Found '{}'.".format( type(value_of_fee_by_currency_id) ), ) enforce( type(self.quantities_by_good_id) == dict, "Invalid type for content 'quantities_by_good_id'. Expected 'dict'. Found '{}'.".format( type(self.quantities_by_good_id) ), ) for ( key_of_quantities_by_good_id, value_of_quantities_by_good_id, ) in self.quantities_by_good_id.items(): enforce( type(key_of_quantities_by_good_id) == str, "Invalid type for dictionary keys in content 'quantities_by_good_id'. Expected 'str'. Found '{}'.".format( type(key_of_quantities_by_good_id) ), ) enforce( type(value_of_quantities_by_good_id) == int, "Invalid type for dictionary values in content 'quantities_by_good_id'. Expected 'int'. Found '{}'.".format( type(value_of_quantities_by_good_id) ), ) enforce( type(self.nonce) == str, "Invalid type for content 'nonce'. Expected 'str'. Found '{}'.".format( type(self.nonce) ), ) enforce( type(self.sender_signature) == str, "Invalid type for content 'sender_signature'. Expected 'str'. Found '{}'.".format( type(self.sender_signature) ), ) enforce( type(self.counterparty_signature) == str, "Invalid type for content 'counterparty_signature'. Expected 'str'. Found '{}'.".format( type(self.counterparty_signature) ), ) elif self.performative == TacMessage.Performative.CANCELLED: expected_nb_of_contents = 0 elif self.performative == TacMessage.Performative.GAME_DATA: expected_nb_of_contents = 9 enforce( type(self.amount_by_currency_id) == dict, "Invalid type for content 'amount_by_currency_id'. Expected 'dict'. Found '{}'.".format( type(self.amount_by_currency_id) ), ) for ( key_of_amount_by_currency_id, value_of_amount_by_currency_id, ) in self.amount_by_currency_id.items(): enforce( type(key_of_amount_by_currency_id) == str, "Invalid type for dictionary keys in content 'amount_by_currency_id'. Expected 'str'. Found '{}'.".format( type(key_of_amount_by_currency_id) ), ) enforce( type(value_of_amount_by_currency_id) == int, "Invalid type for dictionary values in content 'amount_by_currency_id'. Expected 'int'. Found '{}'.".format( type(value_of_amount_by_currency_id) ), ) enforce( type(self.exchange_params_by_currency_id) == dict, "Invalid type for content 'exchange_params_by_currency_id'. Expected 'dict'. Found '{}'.".format( type(self.exchange_params_by_currency_id) ), ) for ( key_of_exchange_params_by_currency_id, value_of_exchange_params_by_currency_id, ) in self.exchange_params_by_currency_id.items(): enforce( type(key_of_exchange_params_by_currency_id) == str, "Invalid type for dictionary keys in content 'exchange_params_by_currency_id'. Expected 'str'. Found '{}'.".format( type(key_of_exchange_params_by_currency_id) ), ) enforce( type(value_of_exchange_params_by_currency_id) == float, "Invalid type for dictionary values in content 'exchange_params_by_currency_id'. Expected 'float'. Found '{}'.".format( type(value_of_exchange_params_by_currency_id) ), ) enforce( type(self.quantities_by_good_id) == dict, "Invalid type for content 'quantities_by_good_id'. Expected 'dict'. Found '{}'.".format( type(self.quantities_by_good_id) ), ) for ( key_of_quantities_by_good_id, value_of_quantities_by_good_id, ) in self.quantities_by_good_id.items(): enforce( type(key_of_quantities_by_good_id) == str, "Invalid type for dictionary keys in content 'quantities_by_good_id'. Expected 'str'. Found '{}'.".format( type(key_of_quantities_by_good_id) ), ) enforce( type(value_of_quantities_by_good_id) == int, "Invalid type for dictionary values in content 'quantities_by_good_id'. Expected 'int'. Found '{}'.".format( type(value_of_quantities_by_good_id) ), ) enforce( type(self.utility_params_by_good_id) == dict, "Invalid type for content 'utility_params_by_good_id'. Expected 'dict'. Found '{}'.".format( type(self.utility_params_by_good_id) ), ) for ( key_of_utility_params_by_good_id, value_of_utility_params_by_good_id, ) in self.utility_params_by_good_id.items(): enforce( type(key_of_utility_params_by_good_id) == str, "Invalid type for dictionary keys in content 'utility_params_by_good_id'. Expected 'str'. Found '{}'.".format( type(key_of_utility_params_by_good_id) ), ) enforce( type(value_of_utility_params_by_good_id) == float, "Invalid type for dictionary values in content 'utility_params_by_good_id'. Expected 'float'. Found '{}'.".format( type(value_of_utility_params_by_good_id) ), ) enforce( type(self.fee_by_currency_id) == dict, "Invalid type for content 'fee_by_currency_id'. Expected 'dict'. Found '{}'.".format( type(self.fee_by_currency_id) ), ) for ( key_of_fee_by_currency_id, value_of_fee_by_currency_id, ) in self.fee_by_currency_id.items(): enforce( type(key_of_fee_by_currency_id) == str, "Invalid type for dictionary keys in content 'fee_by_currency_id'. Expected 'str'. Found '{}'.".format( type(key_of_fee_by_currency_id) ), ) enforce( type(value_of_fee_by_currency_id) == int, "Invalid type for dictionary values in content 'fee_by_currency_id'. Expected 'int'. Found '{}'.".format( type(value_of_fee_by_currency_id) ), ) enforce( type(self.agent_addr_to_name) == dict, "Invalid type for content 'agent_addr_to_name'. Expected 'dict'. Found '{}'.".format( type(self.agent_addr_to_name) ), ) for ( key_of_agent_addr_to_name, value_of_agent_addr_to_name, ) in self.agent_addr_to_name.items(): enforce( type(key_of_agent_addr_to_name) == str, "Invalid type for dictionary keys in content 'agent_addr_to_name'. Expected 'str'. Found '{}'.".format( type(key_of_agent_addr_to_name) ), ) enforce( type(value_of_agent_addr_to_name) == str, "Invalid type for dictionary values in content 'agent_addr_to_name'. Expected 'str'. Found '{}'.".format( type(value_of_agent_addr_to_name) ), ) enforce( type(self.currency_id_to_name) == dict, "Invalid type for content 'currency_id_to_name'. Expected 'dict'. Found '{}'.".format( type(self.currency_id_to_name) ), ) for ( key_of_currency_id_to_name, value_of_currency_id_to_name, ) in self.currency_id_to_name.items(): enforce( type(key_of_currency_id_to_name) == str, "Invalid type for dictionary keys in content 'currency_id_to_name'. Expected 'str'. Found '{}'.".format( type(key_of_currency_id_to_name) ), ) enforce( type(value_of_currency_id_to_name) == str, "Invalid type for dictionary values in content 'currency_id_to_name'. Expected 'str'. Found '{}'.".format( type(value_of_currency_id_to_name) ), ) enforce( type(self.good_id_to_name) == dict, "Invalid type for content 'good_id_to_name'. Expected 'dict'. Found '{}'.".format( type(self.good_id_to_name) ), ) for ( key_of_good_id_to_name, value_of_good_id_to_name, ) in self.good_id_to_name.items(): enforce( type(key_of_good_id_to_name) == str, "Invalid type for dictionary keys in content 'good_id_to_name'. Expected 'str'. Found '{}'.".format( type(key_of_good_id_to_name) ), ) enforce( type(value_of_good_id_to_name) == str, "Invalid type for dictionary values in content 'good_id_to_name'. Expected 'str'. Found '{}'.".format( type(value_of_good_id_to_name) ), ) enforce( type(self.version_id) == str, "Invalid type for content 'version_id'. Expected 'str'. Found '{}'.".format( type(self.version_id) ), ) if self.is_set("info"): expected_nb_of_contents += 1 info = cast(Dict[str, str], self.info) enforce( type(info) == dict, "Invalid type for content 'info'. Expected 'dict'. Found '{}'.".format( type(info) ), ) for key_of_info, value_of_info in info.items(): enforce( type(key_of_info) == str, "Invalid type for dictionary keys in content 'info'. Expected 'str'. Found '{}'.".format( type(key_of_info) ), ) enforce( type(value_of_info) == str, "Invalid type for dictionary values in content 'info'. Expected 'str'. Found '{}'.".format( type(value_of_info) ), ) elif self.performative == TacMessage.Performative.TRANSACTION_CONFIRMATION: expected_nb_of_contents = 3 enforce( type(self.transaction_id) == str, "Invalid type for content 'transaction_id'. Expected 'str'. Found '{}'.".format( type(self.transaction_id) ), ) enforce( type(self.amount_by_currency_id) == dict, "Invalid type for content 'amount_by_currency_id'. Expected 'dict'. Found '{}'.".format( type(self.amount_by_currency_id) ), ) for ( key_of_amount_by_currency_id, value_of_amount_by_currency_id, ) in self.amount_by_currency_id.items(): enforce( type(key_of_amount_by_currency_id) == str, "Invalid type for dictionary keys in content 'amount_by_currency_id'. Expected 'str'. Found '{}'.".format( type(key_of_amount_by_currency_id) ), ) enforce( type(value_of_amount_by_currency_id) == int, "Invalid type for dictionary values in content 'amount_by_currency_id'. Expected 'int'. Found '{}'.".format( type(value_of_amount_by_currency_id) ), ) enforce( type(self.quantities_by_good_id) == dict, "Invalid type for content 'quantities_by_good_id'. Expected 'dict'. Found '{}'.".format( type(self.quantities_by_good_id) ), ) for ( key_of_quantities_by_good_id, value_of_quantities_by_good_id, ) in self.quantities_by_good_id.items(): enforce( type(key_of_quantities_by_good_id) == str, "Invalid type for dictionary keys in content 'quantities_by_good_id'. Expected 'str'. Found '{}'.".format( type(key_of_quantities_by_good_id) ), ) enforce( type(value_of_quantities_by_good_id) == int, "Invalid type for dictionary values in content 'quantities_by_good_id'. Expected 'int'. Found '{}'.".format( type(value_of_quantities_by_good_id) ), ) elif self.performative == TacMessage.Performative.TAC_ERROR: expected_nb_of_contents = 1 enforce( type(self.error_code) == CustomErrorCode, "Invalid type for content 'error_code'. Expected 'ErrorCode'. Found '{}'.".format( type(self.error_code) ), ) if self.is_set("info"): expected_nb_of_contents += 1 info = cast(Dict[str, str], self.info) enforce( type(info) == dict, "Invalid type for content 'info'. Expected 'dict'. Found '{}'.".format( type(info) ), ) for key_of_info, value_of_info in info.items(): enforce( type(key_of_info) == str, "Invalid type for dictionary keys in content 'info'. Expected 'str'. Found '{}'.".format( type(key_of_info) ), ) enforce( type(value_of_info) == str, "Invalid type for dictionary values in content 'info'. Expected 'str'. Found '{}'.".format( type(value_of_info) ), ) # Check correct content count enforce( expected_nb_of_contents == actual_nb_of_contents, "Incorrect number of contents. Expected {}. Found {}".format( expected_nb_of_contents, actual_nb_of_contents ), ) # Light Protocol Rule 3 if self.message_id == 1: enforce( self.target == 0, "Invalid 'target'. Expected 0 (because 'message_id' is 1). Found {}.".format( self.target ), ) else: enforce( 0 < self.target < self.message_id, "Invalid 'target'. Expected an integer between 1 and {} inclusive. Found {}.".format( self.message_id - 1, self.target, ), ) except (AEAEnforceError, ValueError, KeyError) as e: _default_logger.error(str(e)) return False return True
def test_get_active_handlers_skill_id_none(self): """Test get active handlers with skill id None.""" protocol_id = PublicId.from_str("author/name:0.1.0") active_handlers = self.filter.get_active_handlers(protocol_id, skill_id=None) assert len(active_handlers) == 0
"""This module contains base classes for the ledger API connection.""" import asyncio from abc import ABC, abstractmethod from asyncio import Task from concurrent.futures._base import Executor from typing import Any, Callable, Dict, Optional from aea.configurations.base import PublicId from aea.connections.base import ConnectionStatus from aea.crypto.base import LedgerApi from aea.crypto.registries import Registry, ledger_apis_registry from aea.helpers.dialogue.base import Dialogue, Dialogues from aea.mail.base import Envelope from aea.protocols.base import Message CONNECTION_ID = PublicId.from_str("fetchai/ledger:0.2.0") class RequestDispatcher(ABC): """Base class for a request dispatcher.""" TIMEOUT = 3 MAX_ATTEMPTS = 120 def __init__( self, connection_status: ConnectionStatus, loop: Optional[asyncio.AbstractEventLoop] = None, executor: Optional[Executor] = None, api_configs: Optional[Dict[str, Dict[str, str]]] = None, ):
def setup_class(cls): """Set the test up.""" cls.runner = CliRunner() cls.agent_name = "myagent" cls.connection_id = PublicId.from_str("fetchai/http_client:0.5.0") cls.connection_author = cls.connection_id.author cls.connection_name = cls.connection_id.name cls.cwd = os.getcwd() cls.t = tempfile.mkdtemp() # copy the 'packages' directory in the parent of the agent folder. shutil.copytree(Path(ROOT_DIR, "packages"), Path(cls.t, "packages")) os.chdir(cls.t) result = cls.runner.invoke( cli, [*CLI_LOG_OPTION, "init", "--local", "--author", AUTHOR]) assert result.exit_code == 0 result = cls.runner.invoke( cli, [*CLI_LOG_OPTION, "create", "--local", cls.agent_name], standalone_mode=False, ) assert result.exit_code == 0 os.chdir(Path(cls.t, cls.agent_name)) result = cls.runner.invoke( cli, [ *CLI_LOG_OPTION, "add", "--local", "connection", str(cls.connection_id) ], standalone_mode=False, ) assert result.exit_code == 0 result = cls.runner.invoke( cli, [ *CLI_LOG_OPTION, "config", "set", "agent.default_connection", "fetchai/http_client:0.5.0", ], ) assert result.exit_code == 0 connection_module_path = Path( cls.t, cls.agent_name, "vendor", "fetchai", "connections", cls.connection_name, "connection.py", ) connection_module_path.unlink() cls.relative_connection_module_path = connection_module_path.relative_to( Path(cls.t, cls.agent_name)) cls.result = cls.runner.invoke( cli, [ "--skip-consistency-check", *CLI_LOG_OPTION, "run", "--connections", str(cls.connection_id), ], standalone_mode=False, )
# # ------------------------------------------------------------------------------ """This module contains the FET ERC20 contract definition.""" import logging from aea.common import Address from aea.configurations.base import PublicId from aea.contracts.base import Contract from aea.crypto.base import LedgerApi from aea.crypto.ethereum import EthereumApi _default_logger = logging.getLogger( "aea.packages.fetchai.contracts.fet_erc20.contract") PUBLIC_ID = PublicId.from_str("fetchai/fet_erc20:0.3.0") class FetERC20(Contract): """The FetERC20 contract class which acts as a bridge between AEA framework and ERC20 ABI.""" contract_id = PUBLIC_ID @classmethod def get_approve_transaction( cls, ledger_api: LedgerApi, contract_address: Address, from_address: Address, spender: Address, amount: int,
SkillId, ) from aea.decision_maker.messages.base import InternalMessage from aea.decision_maker.messages.transaction import TransactionMessage from aea.mail.base import EnvelopeContext from aea.protocols.base import Message from aea.registries.resources import Resources from aea.skills.base import Behaviour, Handler, Model from aea.skills.tasks import Task logger = logging.getLogger(__name__) PACKAGE_NAME_REGEX = re.compile( "^([A-Z0-9]|[A-Z0-9][A-Z0-9._-]*[A-Z0-9])$", re.IGNORECASE ) INTERNAL_PROTOCOL_ID = PublicId.from_str("fetchai/internal:0.1.0") DECISION_MAKER = "decision_maker" Item = TypeVar("Item") ItemId = TypeVar("ItemId") ComponentId = Tuple[SkillId, str] SkillComponentType = TypeVar("SkillComponentType", Handler, Behaviour, Task, Model) class Filter: """This class implements the filter of an AEA.""" def __init__(self, resources: Resources, decision_maker_out_queue: Queue): """ Instantiate the filter.
def test_soef(): """Perform tests over real network.""" # First run OEF in a separate terminal: python scripts/oef/launch.py -c ./scripts/oef/launch_config.json crypto = make_crypto(DEFAULT_LEDGER) identity = Identity("", address=crypto.address) oef_search_dialogues = OefSearchDialogues(crypto.address) # create the connection and multiplexer objects configuration = ConnectionConfig( api_key="TwiCIriSl0mLahw17pyqoA", soef_addr="soef.fetch.ai", soef_port=9002, restricted_to_protocols={PublicId.from_str("fetchai/oef_search:0.4.0")}, connection_id=SOEFConnection.connection_id, ) soef_connection = SOEFConnection(configuration=configuration, identity=identity,) multiplexer = Multiplexer([soef_connection]) try: # Set the multiplexer running in a different thread t = Thread(target=multiplexer.connect) t.start() wait_for_condition(lambda: multiplexer.is_connected, timeout=5) # register an agent with location agent_location = Location(52.2057092, 2.1183431) service_instance = {"location": agent_location} service_description = Description( service_instance, data_model=models.AGENT_LOCATION_MODEL ) message = OefSearchMessage( performative=OefSearchMessage.Performative.REGISTER_SERVICE, dialogue_reference=oef_search_dialogues.new_self_initiated_dialogue_reference(), service_description=service_description, ) message.counterparty = SOEFConnection.connection_id.latest sending_dialogue = oef_search_dialogues.update(message) assert sending_dialogue is not None envelope = Envelope( to=message.counterparty, sender=message.sender, protocol_id=message.protocol_id, message=message, ) logger.info( "Registering agent at location=({},{}) by agent={}".format( agent_location.latitude, agent_location.longitude, crypto.address, ) ) multiplexer.put(envelope) # register personality pieces service_instance = {"piece": "genus", "value": "service"} service_description = Description( service_instance, data_model=models.AGENT_PERSONALITY_MODEL ) message = OefSearchMessage( performative=OefSearchMessage.Performative.REGISTER_SERVICE, dialogue_reference=oef_search_dialogues.new_self_initiated_dialogue_reference(), service_description=service_description, ) message.counterparty = SOEFConnection.connection_id.latest sending_dialogue = oef_search_dialogues.update(message) assert sending_dialogue is not None envelope = Envelope( to=message.counterparty, sender=message.sender, protocol_id=message.protocol_id, message=message, ) logger.info("Registering agent personality") multiplexer.put(envelope) # register service key service_instance = {"key": "test", "value": "test"} service_description = Description( service_instance, data_model=models.SET_SERVICE_KEY_MODEL ) message = OefSearchMessage( performative=OefSearchMessage.Performative.REGISTER_SERVICE, dialogue_reference=oef_search_dialogues.new_self_initiated_dialogue_reference(), service_description=service_description, ) message.counterparty = SOEFConnection.connection_id.latest sending_dialogue = oef_search_dialogues.update(message) assert sending_dialogue is not None envelope = Envelope( to=message.counterparty, sender=message.sender, protocol_id=message.protocol_id, message=message, ) logger.info("Registering agent service key") multiplexer.put(envelope) # find agents near me radius = 0.1 close_to_my_service = Constraint( "location", ConstraintType("distance", (agent_location, radius)) ) closeness_query = Query( [close_to_my_service], model=models.AGENT_LOCATION_MODEL ) message = OefSearchMessage( performative=OefSearchMessage.Performative.SEARCH_SERVICES, dialogue_reference=oef_search_dialogues.new_self_initiated_dialogue_reference(), query=closeness_query, ) message.counterparty = SOEFConnection.connection_id.latest sending_dialogue = oef_search_dialogues.update(message) assert sending_dialogue is not None search_envelope = Envelope( to=message.counterparty, sender=message.sender, protocol_id=message.protocol_id, message=message, ) logger.info( "Searching for agents in radius={} of myself at location=({},{})".format( radius, agent_location.latitude, agent_location.longitude, ) ) multiplexer.put(search_envelope) wait_for_condition(lambda: not multiplexer.in_queue.empty(), timeout=20) # check for search results envelope = multiplexer.get() orig_message = envelope.message assert orig_message.performative == OefSearchMessage.Performative.SEARCH_RESULT assert len(orig_message.agents) >= 0 message = copy.copy(orig_message) message.is_incoming = True # TODO: fix message.counterparty = orig_message.sender # TODO; fix receiving_dialogue = oef_search_dialogues.update(message) assert sending_dialogue == receiving_dialogue # double send to check issue with too many requests message = OefSearchMessage( performative=OefSearchMessage.Performative.SEARCH_SERVICES, dialogue_reference=oef_search_dialogues.new_self_initiated_dialogue_reference(), query=closeness_query, ) message.counterparty = SOEFConnection.connection_id.latest sending_dialogue = oef_search_dialogues.update(message) assert sending_dialogue is not None search_envelope = Envelope( to=message.counterparty, sender=message.sender, protocol_id=message.protocol_id, message=message, ) multiplexer.put(search_envelope) wait_for_condition(lambda: not multiplexer.in_queue.empty(), timeout=20) # check for search results envelope = multiplexer.get() message = envelope.message assert message.performative == OefSearchMessage.Performative.SEARCH_RESULT # find agents near me with filter radius = 0.1 close_to_my_service = Constraint( "location", ConstraintType("distance", (agent_location, radius)) ) personality_filters = [ Constraint("genus", ConstraintType("==", "vehicle")), Constraint( "classification", ConstraintType("==", "mobility.railway.train") ), ] service_key_filters = [ Constraint("test_key", ConstraintType("==", "test_value")), ] constraints = [close_to_my_service] + personality_filters + service_key_filters assert len(constraints) == 4 closeness_query = Query(constraints) message = OefSearchMessage( performative=OefSearchMessage.Performative.SEARCH_SERVICES, dialogue_reference=oef_search_dialogues.new_self_initiated_dialogue_reference(), query=closeness_query, ) message.counterparty = SOEFConnection.connection_id.latest sending_dialogue = oef_search_dialogues.update(message) assert sending_dialogue is not None envelope = Envelope( to=message.counterparty, sender=message.sender, protocol_id=message.protocol_id, message=message, ) logger.info( "Searching for agents in radius={} of myself at location=({},{}) with personality filters".format( radius, agent_location.latitude, agent_location.longitude, ) ) time.sleep(3) # cause requests rate limit on server :( multiplexer.put(envelope) wait_for_condition(lambda: not multiplexer.in_queue.empty(), timeout=20) envelope = multiplexer.get() orig_message = envelope.message assert orig_message.performative == OefSearchMessage.Performative.SEARCH_RESULT assert len(orig_message.agents) >= 0 message = copy.copy(orig_message) message.is_incoming = True # TODO: fix message.counterparty = orig_message.sender # TODO; fix receiving_dialogue = oef_search_dialogues.update(message) assert sending_dialogue == receiving_dialogue # test ping command service_description = Description({}, data_model=models.PING_MODEL) message = OefSearchMessage( performative=OefSearchMessage.Performative.REGISTER_SERVICE, dialogue_reference=oef_search_dialogues.new_self_initiated_dialogue_reference(), service_description=service_description, ) message.counterparty = SOEFConnection.connection_id.latest sending_dialogue = oef_search_dialogues.update(message) assert sending_dialogue is not None envelope = Envelope( to=message.counterparty, sender=crypto.address, protocol_id=message.protocol_id, message=message, ) logger.info("Pinging") multiplexer.put(envelope) time.sleep(3) assert multiplexer.in_queue.empty() finally: # Shut down the multiplexer multiplexer.disconnect() t.join()
# -*- coding: utf-8 -*- # ------------------------------------------------------------------------------ # # Copyright 2018-2019 Fetch.AI Limited # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # # ------------------------------------------------------------------------------ """This module contains the implementation of the aries_alice skill.""" from aea.configurations.base import PublicId PUBLIC_ID = PublicId.from_str("fetchai/aries_alice:0.11.0")
async def test_handle(): """Tests handle method of an agent.""" with LocalNode() as node: agent_name = "MyAgent" private_key_path = os.path.join(CUR_PATH, "data", "fet_private_key.txt") builder = AEABuilder() builder.set_name(agent_name) builder.add_private_key(FETCHAI, private_key_path) builder.add_protocol( Path(ROOT_DIR, "packages", "fetchai", "protocols", "oef_search")) builder.add_connection( Path(ROOT_DIR, "packages", "fetchai", "connections", "local")) builder.set_default_connection( PublicId.from_str("fetchai/local:0.1.0")) builder.add_skill(Path(CUR_PATH, "data", "dummy_skill")) aea = builder.build( connection_ids=[PublicId.from_str("fetchai/local:0.1.0")]) # This is a temporary workaround to feed the local node to the OEF Local connection # TODO remove it. list(aea._connections)[0]._local_node = node msg = DefaultMessage( dialogue_reference=("", ""), message_id=1, target=0, performative=DefaultMessage.Performative.BYTES, content=b"hello", ) message_bytes = DefaultSerializer().encode(msg) envelope = Envelope( to=aea.identity.address, sender=aea.identity.address, protocol_id=UNKNOWN_PROTOCOL_PUBLIC_ID, message=message_bytes, ) with run_in_thread(aea.start, timeout=5, on_exit=aea.stop): wait_for_condition( lambda: aea._main_loop and aea._main_loop.is_running, timeout=10) dummy_skill = aea.resources.get_skill(DUMMY_SKILL_PUBLIC_ID) dummy_handler = dummy_skill.handlers["dummy"] aea.outbox.put(envelope) wait_for_condition( lambda: len(dummy_handler.handled_messages) == 1, timeout=1, ) # DECODING ERROR envelope = Envelope( to=aea.identity.address, sender=aea.identity.address, protocol_id=DefaultMessage.protocol_id, message=b"", ) # send envelope via localnode back to agent aea.outbox.put(envelope) """ inbox twice cause first message is invalid. generates error message and it accepted """ wait_for_condition( lambda: len(dummy_handler.handled_messages) == 2, timeout=1, ) # UNSUPPORTED SKILL msg = FipaSerializer().encode( FipaMessage( performative=FipaMessage.Performative.ACCEPT, message_id=1, dialogue_reference=(str(0), ""), target=0, )) envelope = Envelope( to=aea.identity.address, sender=aea.identity.address, protocol_id=FipaMessage.protocol_id, message=msg, ) # send envelope via localnode back to agent aea.outbox.put(envelope) wait_for_condition( lambda: len(dummy_handler.handled_messages) == 3, timeout=1, ) aea.stop()
# -*- coding: utf-8 -*- # ------------------------------------------------------------------------------ # # Copyright 2018-2019 Fetch.AI Limited # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # # ------------------------------------------------------------------------------ """This module contains the implementation of the car park detection skill.""" from aea.configurations.base import PublicId PUBLIC_ID = PublicId.from_str("fetchai/carpark_detection:0.19.0")
def test_initialize_aea_programmatically(): """Test that we can initialize an AEA programmatically.""" with LocalNode() as node: agent_name = "MyAgent" private_key_path = os.path.join(CUR_PATH, "data", "fet_private_key.txt") builder = AEABuilder() builder.set_name(agent_name) builder.add_private_key(FETCHAI, private_key_path) builder.add_protocol( Path(ROOT_DIR, "packages", "fetchai", "protocols", "oef_search")) builder.add_connection( Path(ROOT_DIR, "packages", "fetchai", "connections", "local")) builder.set_default_connection( PublicId.from_str("fetchai/local:0.1.0")) builder.add_skill(Path(CUR_PATH, "data", "dummy_skill")) aea = builder.build( connection_ids=[PublicId.from_str("fetchai/local:0.1.0")]) list(aea._connections)[0]._local_node = node expected_message = DefaultMessage( dialogue_reference=("", ""), message_id=1, target=0, performative=DefaultMessage.Performative.BYTES, content=b"hello", ) expected_message.counterparty = aea.identity.address envelope = Envelope( to=aea.identity.address, sender=aea.identity.address, protocol_id=DefaultMessage.protocol_id, message=DefaultSerializer().encode(expected_message), ) with run_in_thread(aea.start, timeout=5, on_exit=aea.stop): wait_for_condition( lambda: aea._main_loop and aea._main_loop.is_running, timeout=10) aea.outbox.put(envelope) dummy_skill_id = DUMMY_SKILL_PUBLIC_ID dummy_behaviour_name = "dummy" dummy_behaviour = aea.resources.get_behaviour( dummy_skill_id, dummy_behaviour_name) wait_for_condition(lambda: dummy_behaviour is not None, timeout=10) wait_for_condition(lambda: dummy_behaviour.nb_act_called > 0, timeout=10) # TODO the previous code caused an error: # _pickle.PicklingError: Can't pickle <class 'tasks.DummyTask'>: import of module 'tasks' failed dummy_task = DummyTask() task_id = aea.task_manager.enqueue_task(dummy_task) async_result = aea.task_manager.get_task_result(task_id) expected_dummy_task = async_result.get(10.0) wait_for_condition( lambda: expected_dummy_task.nb_execute_called > 0, timeout=10) dummy_handler = aea.resources.get_handler( DefaultMessage.protocol_id, dummy_skill_id) dummy_handler_alt = aea.resources._handler_registry.fetch( (dummy_skill_id, "dummy")) wait_for_condition(lambda: dummy_handler == dummy_handler_alt, timeout=10) wait_for_condition(lambda: dummy_handler is not None, timeout=10) wait_for_condition( lambda: len(dummy_handler.handled_messages) == 1, timeout=10) wait_for_condition( lambda: dummy_handler.handled_messages[0] == expected_message, timeout=10, )
from typing import Optional, Union, cast from aiohttp import web # type: ignore from aea.configurations.base import ConnectionConfig, PublicId from aea.connections.base import Connection from aea.mail.base import Address, Envelope, EnvelopeContext, URI from packages.fetchai.protocols.http.message import HttpMessage from packages.fetchai.protocols.http.serialization import HttpSerializer SUCCESS = 200 NOT_FOUND = 404 REQUEST_TIMEOUT = 408 SERVER_ERROR = 500 PUBLIC_ID = PublicId.from_str("fetchai/webhook:0.1.0") logger = logging.getLogger("aea.packages.fetchai.connections.webhook") RequestId = str class WebhookChannel: """A wrapper for a Webhook.""" def __init__( self, agent_address: Address, webhook_address: Address, webhook_port: int, webhook_url_path: str, connection_id: PublicId,
from typing import Dict, List, Optional, cast from aea_ledger_cosmos import CosmosApi from aea_ledger_ethereum import EthereumApi from aea_ledger_fetchai import FetchAIApi from aea.common import Address, JSONLike from aea.configurations.base import PublicId from aea.contracts.base import Contract from aea.crypto.base import LedgerApi _default_logger = logging.getLogger("aea.packages.fetchai.contracts.erc1155.contract") MAX_UINT_256 = 2 ^ 256 - 1 PUBLIC_ID = PublicId.from_str("fetchai/erc1155:0.18.0") def keccak256(input_: bytes) -> bytes: """Compute hash.""" return bytes(bytearray.fromhex(EthereumApi.get_hash(input_)[2:])) class ERC1155Contract(Contract): """The ERC1155 contract class which acts as a bridge between AEA framework and ERC1155 ABI.""" contract_id = PUBLIC_ID @classmethod def generate_token_ids( cls, token_type: int, nb_tokens: int, starting_index: int = 0
LIBP2P_NODE_MODULE_NAME = "libp2p_node" LIBP2P_NODE_LOG_FILE = "libp2p_node.log" LIBP2P_NODE_ENV_FILE = ".env.libp2p" LIBP2P_NODE_CLARGS = list() # type: List[str] LIBP2P_NODE_DEPS_DOWNLOAD_TIMEOUT = 660 # time to download ~66Mb PIPE_CONN_TIMEOUT = 10.0 # TOFIX(LR) not sure is needed LIBP2P = "libp2p" PUBLIC_ID = PublicId.from_str("fetchai/p2p_libp2p:0.7.0") MultiAddr = str SUPPORTED_LEDGER_IDS = ["fetchai", "cosmos", "ethereum"] async def _golang_module_build_async( path: str, log_file_desc: IO[str], timeout: float = LIBP2P_NODE_DEPS_DOWNLOAD_TIMEOUT, logger: logging.Logger = _default_logger, ) -> int: """ Builds go module located at `path`, downloads necessary dependencies
class StateUpdateMessage(Message): """A protocol for state updates to the decision maker state.""" protocol_id = PublicId.from_str("fetchai/state_update:0.9.0") class Performative(Message.Performative): """Performatives for the state_update protocol.""" APPLY = "apply" END = "end" INITIALIZE = "initialize" def __str__(self): """Get the string representation.""" return str(self.value) _performatives = {"apply", "end", "initialize"} __slots__: Tuple[str, ...] = tuple() class _SlotsCls: __slots__ = ( "amount_by_currency_id", "dialogue_reference", "exchange_params_by_currency_id", "message_id", "performative", "quantities_by_good_id", "target", "utility_params_by_good_id", ) def __init__( self, performative: Performative, dialogue_reference: Tuple[str, str] = ("", ""), message_id: int = 1, target: int = 0, **kwargs, ): """ Initialise an instance of StateUpdateMessage. :param message_id: the message id. :param dialogue_reference: the dialogue reference. :param target: the message target. :param performative: the message performative. """ super().__init__( dialogue_reference=dialogue_reference, message_id=message_id, target=target, performative=StateUpdateMessage.Performative(performative), **kwargs, ) @property def valid_performatives(self) -> Set[str]: """Get valid performatives.""" return self._performatives @property def dialogue_reference(self) -> Tuple[str, str]: """Get the dialogue_reference of the message.""" enforce(self.is_set("dialogue_reference"), "dialogue_reference is not set.") return cast(Tuple[str, str], self.get("dialogue_reference")) @property def message_id(self) -> int: """Get the message_id of the message.""" enforce(self.is_set("message_id"), "message_id is not set.") return cast(int, self.get("message_id")) @property def performative(self) -> Performative: # type: ignore # noqa: F821 """Get the performative of the message.""" enforce(self.is_set("performative"), "performative is not set.") return cast(StateUpdateMessage.Performative, self.get("performative")) @property def target(self) -> int: """Get the target of the message.""" enforce(self.is_set("target"), "target is not set.") return cast(int, self.get("target")) @property def amount_by_currency_id(self) -> Dict[str, int]: """Get the 'amount_by_currency_id' content from the message.""" enforce( self.is_set("amount_by_currency_id"), "'amount_by_currency_id' content is not set.", ) return cast(Dict[str, int], self.get("amount_by_currency_id")) @property def exchange_params_by_currency_id(self) -> Dict[str, float]: """Get the 'exchange_params_by_currency_id' content from the message.""" enforce( self.is_set("exchange_params_by_currency_id"), "'exchange_params_by_currency_id' content is not set.", ) return cast(Dict[str, float], self.get("exchange_params_by_currency_id")) @property def quantities_by_good_id(self) -> Dict[str, int]: """Get the 'quantities_by_good_id' content from the message.""" enforce( self.is_set("quantities_by_good_id"), "'quantities_by_good_id' content is not set.", ) return cast(Dict[str, int], self.get("quantities_by_good_id")) @property def utility_params_by_good_id(self) -> Dict[str, float]: """Get the 'utility_params_by_good_id' content from the message.""" enforce( self.is_set("utility_params_by_good_id"), "'utility_params_by_good_id' content is not set.", ) return cast(Dict[str, float], self.get("utility_params_by_good_id")) def _is_consistent(self) -> bool: """Check that the message follows the state_update protocol.""" try: enforce( type(self.dialogue_reference) == tuple, "Invalid type for 'dialogue_reference'. Expected 'tuple'. Found '{}'." .format(type(self.dialogue_reference)), ) enforce( type(self.dialogue_reference[0]) == str, "Invalid type for 'dialogue_reference[0]'. Expected 'str'. Found '{}'." .format(type(self.dialogue_reference[0])), ) enforce( type(self.dialogue_reference[1]) == str, "Invalid type for 'dialogue_reference[1]'. Expected 'str'. Found '{}'." .format(type(self.dialogue_reference[1])), ) enforce( type(self.message_id) == int, "Invalid type for 'message_id'. Expected 'int'. Found '{}'.". format(type(self.message_id)), ) enforce( type(self.target) == int, "Invalid type for 'target'. Expected 'int'. Found '{}'.". format(type(self.target)), ) # Light Protocol Rule 2 # Check correct performative enforce( type(self.performative) == StateUpdateMessage.Performative, "Invalid 'performative'. Expected either of '{}'. Found '{}'.". format(self.valid_performatives, self.performative), ) # Check correct contents actual_nb_of_contents = len(self._body) - DEFAULT_BODY_SIZE expected_nb_of_contents = 0 if self.performative == StateUpdateMessage.Performative.INITIALIZE: expected_nb_of_contents = 4 enforce( type(self.exchange_params_by_currency_id) == dict, "Invalid type for content 'exchange_params_by_currency_id'. Expected 'dict'. Found '{}'." .format(type(self.exchange_params_by_currency_id)), ) for ( key_of_exchange_params_by_currency_id, value_of_exchange_params_by_currency_id, ) in self.exchange_params_by_currency_id.items(): enforce( type(key_of_exchange_params_by_currency_id) == str, "Invalid type for dictionary keys in content 'exchange_params_by_currency_id'. Expected 'str'. Found '{}'." .format(type(key_of_exchange_params_by_currency_id)), ) enforce( type(value_of_exchange_params_by_currency_id) == float, "Invalid type for dictionary values in content 'exchange_params_by_currency_id'. Expected 'float'. Found '{}'." .format(type(value_of_exchange_params_by_currency_id)), ) enforce( type(self.utility_params_by_good_id) == dict, "Invalid type for content 'utility_params_by_good_id'. Expected 'dict'. Found '{}'." .format(type(self.utility_params_by_good_id)), ) for ( key_of_utility_params_by_good_id, value_of_utility_params_by_good_id, ) in self.utility_params_by_good_id.items(): enforce( type(key_of_utility_params_by_good_id) == str, "Invalid type for dictionary keys in content 'utility_params_by_good_id'. Expected 'str'. Found '{}'." .format(type(key_of_utility_params_by_good_id)), ) enforce( type(value_of_utility_params_by_good_id) == float, "Invalid type for dictionary values in content 'utility_params_by_good_id'. Expected 'float'. Found '{}'." .format(type(value_of_utility_params_by_good_id)), ) enforce( type(self.amount_by_currency_id) == dict, "Invalid type for content 'amount_by_currency_id'. Expected 'dict'. Found '{}'." .format(type(self.amount_by_currency_id)), ) for ( key_of_amount_by_currency_id, value_of_amount_by_currency_id, ) in self.amount_by_currency_id.items(): enforce( type(key_of_amount_by_currency_id) == str, "Invalid type for dictionary keys in content 'amount_by_currency_id'. Expected 'str'. Found '{}'." .format(type(key_of_amount_by_currency_id)), ) enforce( type(value_of_amount_by_currency_id) == int, "Invalid type for dictionary values in content 'amount_by_currency_id'. Expected 'int'. Found '{}'." .format(type(value_of_amount_by_currency_id)), ) enforce( type(self.quantities_by_good_id) == dict, "Invalid type for content 'quantities_by_good_id'. Expected 'dict'. Found '{}'." .format(type(self.quantities_by_good_id)), ) for ( key_of_quantities_by_good_id, value_of_quantities_by_good_id, ) in self.quantities_by_good_id.items(): enforce( type(key_of_quantities_by_good_id) == str, "Invalid type for dictionary keys in content 'quantities_by_good_id'. Expected 'str'. Found '{}'." .format(type(key_of_quantities_by_good_id)), ) enforce( type(value_of_quantities_by_good_id) == int, "Invalid type for dictionary values in content 'quantities_by_good_id'. Expected 'int'. Found '{}'." .format(type(value_of_quantities_by_good_id)), ) elif self.performative == StateUpdateMessage.Performative.APPLY: expected_nb_of_contents = 2 enforce( type(self.amount_by_currency_id) == dict, "Invalid type for content 'amount_by_currency_id'. Expected 'dict'. Found '{}'." .format(type(self.amount_by_currency_id)), ) for ( key_of_amount_by_currency_id, value_of_amount_by_currency_id, ) in self.amount_by_currency_id.items(): enforce( type(key_of_amount_by_currency_id) == str, "Invalid type for dictionary keys in content 'amount_by_currency_id'. Expected 'str'. Found '{}'." .format(type(key_of_amount_by_currency_id)), ) enforce( type(value_of_amount_by_currency_id) == int, "Invalid type for dictionary values in content 'amount_by_currency_id'. Expected 'int'. Found '{}'." .format(type(value_of_amount_by_currency_id)), ) enforce( type(self.quantities_by_good_id) == dict, "Invalid type for content 'quantities_by_good_id'. Expected 'dict'. Found '{}'." .format(type(self.quantities_by_good_id)), ) for ( key_of_quantities_by_good_id, value_of_quantities_by_good_id, ) in self.quantities_by_good_id.items(): enforce( type(key_of_quantities_by_good_id) == str, "Invalid type for dictionary keys in content 'quantities_by_good_id'. Expected 'str'. Found '{}'." .format(type(key_of_quantities_by_good_id)), ) enforce( type(value_of_quantities_by_good_id) == int, "Invalid type for dictionary values in content 'quantities_by_good_id'. Expected 'int'. Found '{}'." .format(type(value_of_quantities_by_good_id)), ) elif self.performative == StateUpdateMessage.Performative.END: expected_nb_of_contents = 0 # Check correct content count enforce( expected_nb_of_contents == actual_nb_of_contents, "Incorrect number of contents. Expected {}. Found {}".format( expected_nb_of_contents, actual_nb_of_contents), ) # Light Protocol Rule 3 if self.message_id == 1: enforce( self.target == 0, "Invalid 'target'. Expected 0 (because 'message_id' is 1). Found {}." .format(self.target), ) else: enforce( 0 < self.target < self.message_id, "Invalid 'target'. Expected an integer between 1 and {} inclusive. Found {}." .format( self.message_id - 1, self.target, ), ) except (AEAEnforceError, ValueError, KeyError) as e: _default_logger.error(str(e)) return False return True
# -*- coding: utf-8 -*- # ------------------------------------------------------------------------------ # # Copyright 2018-2019 Fetch.AI Limited # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # # ------------------------------------------------------------------------------ """This module contains the implementation of the default skill.""" from aea.configurations.base import PublicId PUBLIC_ID = PublicId.from_str("gdp8/env_action_each_turn:0.1.0")
# -*- coding: utf-8 -*- # ------------------------------------------------------------------------------ # # Copyright 2018-2019 Fetch.AI Limited # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # # ------------------------------------------------------------------------------ """This module contains the implementation of the default skill.""" from aea.configurations.base import PublicId PUBLIC_ID = PublicId.from_str("fetchai/thermometer_client:0.19.0")
from aea.common import Address from aea.configurations.base import PublicId from aea.connections.base import Connection, ConnectionStates from aea.exceptions import enforce from aea.helpers.base import locate from aea.mail.base import Envelope, Message from aea.protocols.dialogue.base import Dialogue as BaseDialogue from packages.fetchai.protocols.gym.dialogues import GymDialogue from packages.fetchai.protocols.gym.dialogues import GymDialogues as BaseGymDialogues from packages.fetchai.protocols.gym.message import GymMessage _default_logger = logging.getLogger("aea.packages.fetchai.connections.gym") PUBLIC_ID = PublicId.from_str("fetchai/gym:0.11.0") class GymDialogues(BaseGymDialogues): """The dialogues class keeps track of all gym dialogues.""" def __init__(self, **kwargs) -> None: """ Initialize dialogues. :return: None """ def role_from_first_message( # pylint: disable=unused-argument message: Message, receiver_address: Address) -> BaseDialogue.Role: """Infer the role of the agent from an incoming/outgoing first message
# -*- coding: utf-8 -*- # ------------------------------------------------------------------------------ # # Copyright 2018-2019 Fetch.AI Limited # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # # ------------------------------------------------------------------------------ """This module contains the implementation of the erc-1155 client skill.""" from aea.configurations.base import PublicId PUBLIC_ID = PublicId.from_str("fetchai/erc1155_client:0.16.0")
class YotiMessage(Message): """A protocol for communication between yoti skills and yoti connection.""" protocol_id = PublicId.from_str("fetchai/yoti:0.1.0") protocol_specification_id = PublicId.from_str("fetchai/yoti:0.1.0") class Performative(Message.Performative): """Performatives for the yoti protocol.""" ERROR = "error" GET_PROFILE = "get_profile" PROFILE = "profile" def __str__(self) -> str: """Get the string representation.""" return str(self.value) _performatives = {"error", "get_profile", "profile"} __slots__: Tuple[str, ...] = tuple() class _SlotsCls: __slots__ = ( "args", "dialogue_reference", "dotted_path", "error_code", "error_msg", "info", "message_id", "performative", "target", "token", ) def __init__( self, performative: Performative, dialogue_reference: Tuple[str, str] = ("", ""), message_id: int = 1, target: int = 0, **kwargs: Any, ): """ Initialise an instance of YotiMessage. :param message_id: the message id. :param dialogue_reference: the dialogue reference. :param target: the message target. :param performative: the message performative. """ super().__init__( dialogue_reference=dialogue_reference, message_id=message_id, target=target, performative=YotiMessage.Performative(performative), **kwargs, ) @property def valid_performatives(self) -> Set[str]: """Get valid performatives.""" return self._performatives @property def dialogue_reference(self) -> Tuple[str, str]: """Get the dialogue_reference of the message.""" enforce(self.is_set("dialogue_reference"), "dialogue_reference is not set.") return cast(Tuple[str, str], self.get("dialogue_reference")) @property def message_id(self) -> int: """Get the message_id of the message.""" enforce(self.is_set("message_id"), "message_id is not set.") return cast(int, self.get("message_id")) @property def performative(self) -> Performative: # type: ignore # noqa: F821 """Get the performative of the message.""" enforce(self.is_set("performative"), "performative is not set.") return cast(YotiMessage.Performative, self.get("performative")) @property def target(self) -> int: """Get the target of the message.""" enforce(self.is_set("target"), "target is not set.") return cast(int, self.get("target")) @property def args(self) -> Tuple[str, ...]: """Get the 'args' content from the message.""" enforce(self.is_set("args"), "'args' content is not set.") return cast(Tuple[str, ...], self.get("args")) @property def dotted_path(self) -> str: """Get the 'dotted_path' content from the message.""" enforce(self.is_set("dotted_path"), "'dotted_path' content is not set.") return cast(str, self.get("dotted_path")) @property def error_code(self) -> int: """Get the 'error_code' content from the message.""" enforce(self.is_set("error_code"), "'error_code' content is not set.") return cast(int, self.get("error_code")) @property def error_msg(self) -> str: """Get the 'error_msg' content from the message.""" enforce(self.is_set("error_msg"), "'error_msg' content is not set.") return cast(str, self.get("error_msg")) @property def info(self) -> Dict[str, str]: """Get the 'info' content from the message.""" enforce(self.is_set("info"), "'info' content is not set.") return cast(Dict[str, str], self.get("info")) @property def token(self) -> str: """Get the 'token' content from the message.""" enforce(self.is_set("token"), "'token' content is not set.") return cast(str, self.get("token")) def _is_consistent(self) -> bool: """Check that the message follows the yoti protocol.""" try: enforce( type(self.dialogue_reference) == tuple, "Invalid type for 'dialogue_reference'. Expected 'tuple'. Found '{}'.".format( type(self.dialogue_reference) ), ) enforce( type(self.dialogue_reference[0]) == str, "Invalid type for 'dialogue_reference[0]'. Expected 'str'. Found '{}'.".format( type(self.dialogue_reference[0]) ), ) enforce( type(self.dialogue_reference[1]) == str, "Invalid type for 'dialogue_reference[1]'. Expected 'str'. Found '{}'.".format( type(self.dialogue_reference[1]) ), ) enforce( type(self.message_id) == int, "Invalid type for 'message_id'. Expected 'int'. Found '{}'.".format( type(self.message_id) ), ) enforce( type(self.target) == int, "Invalid type for 'target'. Expected 'int'. Found '{}'.".format( type(self.target) ), ) # Light Protocol Rule 2 # Check correct performative enforce( type(self.performative) == YotiMessage.Performative, "Invalid 'performative'. Expected either of '{}'. Found '{}'.".format( self.valid_performatives, self.performative ), ) # Check correct contents actual_nb_of_contents = len(self._body) - DEFAULT_BODY_SIZE expected_nb_of_contents = 0 if self.performative == YotiMessage.Performative.GET_PROFILE: expected_nb_of_contents = 3 enforce( type(self.token) == str, "Invalid type for content 'token'. Expected 'str'. Found '{}'.".format( type(self.token) ), ) enforce( type(self.dotted_path) == str, "Invalid type for content 'dotted_path'. Expected 'str'. Found '{}'.".format( type(self.dotted_path) ), ) enforce( type(self.args) == tuple, "Invalid type for content 'args'. Expected 'tuple'. Found '{}'.".format( type(self.args) ), ) enforce( all(type(element) == str for element in self.args), "Invalid type for tuple elements in content 'args'. Expected 'str'.", ) elif self.performative == YotiMessage.Performative.PROFILE: expected_nb_of_contents = 1 enforce( type(self.info) == dict, "Invalid type for content 'info'. Expected 'dict'. Found '{}'.".format( type(self.info) ), ) for key_of_info, value_of_info in self.info.items(): enforce( type(key_of_info) == str, "Invalid type for dictionary keys in content 'info'. Expected 'str'. Found '{}'.".format( type(key_of_info) ), ) enforce( type(value_of_info) == str, "Invalid type for dictionary values in content 'info'. Expected 'str'. Found '{}'.".format( type(value_of_info) ), ) elif self.performative == YotiMessage.Performative.ERROR: expected_nb_of_contents = 2 enforce( type(self.error_code) == int, "Invalid type for content 'error_code'. Expected 'int'. Found '{}'.".format( type(self.error_code) ), ) enforce( type(self.error_msg) == str, "Invalid type for content 'error_msg'. Expected 'str'. Found '{}'.".format( type(self.error_msg) ), ) # Check correct content count enforce( expected_nb_of_contents == actual_nb_of_contents, "Incorrect number of contents. Expected {}. Found {}".format( expected_nb_of_contents, actual_nb_of_contents ), ) # Light Protocol Rule 3 if self.message_id == 1: enforce( self.target == 0, "Invalid 'target'. Expected 0 (because 'message_id' is 1). Found {}.".format( self.target ), ) except (AEAEnforceError, ValueError, KeyError) as e: _default_logger.error(str(e)) return False return True
# -*- coding: utf-8 -*- # ------------------------------------------------------------------------------ # # Copyright 2018-2019 Fetch.AI Limited # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # # ------------------------------------------------------------------------------ """This module contains the implementation of the generic seller skill.""" from aea.configurations.base import PublicId PUBLIC_ID = PublicId.from_str("fetchai/generic_seller:0.16.0")