Ejemplo n.º 1
0
    def from_dir(cls, directory: str) -> "Protocol":
        """
        Load a protocol from a directory.

        :param directory: the skill directory.
        :param agent_context: the agent's context
        :return: the Protocol object.
        :raises Exception: if the parsing failed.
        """
        # check if there is the config file. If not, then return None.
        protocol_loader = ConfigLoader("protocol-config_schema.json",
                                       ProtocolConfig)
        protocol_config = protocol_loader.load(
            open(os.path.join(directory, DEFAULT_PROTOCOL_CONFIG_FILE)))
        protocol_module = load_module("protocols",
                                      Path(directory, "serialization.py"))
        add_agent_component_module_to_sys_modules("protocol",
                                                  protocol_config.name,
                                                  protocol_config.author,
                                                  protocol_module)
        classes = inspect.getmembers(protocol_module, inspect.isclass)
        serializer_classes = list(
            filter(lambda x: re.match("\\w+Serializer", x[0]), classes))
        assert len(
            serializer_classes) == 1, "Not exactly one serializer detected."
        serializer_class = serializer_classes[0][1]

        protocol_id = PublicId(protocol_config.author, protocol_config.name,
                               protocol_config.version)
        protocol = Protocol(protocol_id, serializer_class(), protocol_config)
        return protocol
Ejemplo n.º 2
0
def verify_or_create_private_keys(ctx: Context) -> None:
    """
    Verify or create private keys.

    :param ctx: Context
    """
    path = Path(DEFAULT_AEA_CONFIG_FILE)
    agent_loader = ConfigLoader("aea-config_schema.json", AgentConfig)
    fp = path.open(mode="r", encoding="utf-8")
    aea_conf = agent_loader.load(fp)

    for identifier, _value in aea_conf.private_key_paths.read_all():
        if identifier not in registry.supported_crypto_ids:
            ValueError("Unsupported identifier in private key paths.")

    for identifier, private_key_path in IDENTIFIER_TO_KEY_FILES.items():
        config_private_key_path = aea_conf.private_key_paths.read(identifier)
        if config_private_key_path is None:
            create_private_key(identifier)
            aea_conf.private_key_paths.update(identifier, private_key_path)
        else:
            try:
                _try_validate_private_key_path(identifier, private_key_path)
            except FileNotFoundError:  # pragma: no cover
                raise click.ClickException(
                    "File {} for private key {} not found.".format(
                        repr(private_key_path), identifier,
                    )
                )

    # update aea config
    path = Path(DEFAULT_AEA_CONFIG_FILE)
    fp = path.open(mode="w", encoding="utf-8")
    agent_loader.dump(aea_conf, fp)
    ctx.agent_config = aea_conf
Ejemplo n.º 3
0
    def _add_protocol(self, directory: str, protocol_name: str):
        """
        Add a protocol.

        :param directory: the agent's resources directory.
        :param protocol_name: the name of the protocol to be added.
        :return: None
        """
        # get the serializer
        serialization_spec = importlib.util.spec_from_file_location("serialization",
                                                                    os.path.join(directory, "protocols", protocol_name, "serialization.py"))
        serialization_module = importlib.util.module_from_spec(serialization_spec)
        serialization_spec.loader.exec_module(serialization_module)  # type: ignore
        classes = inspect.getmembers(serialization_module, inspect.isclass)
        serializer_classes = list(filter(lambda x: re.match("\\w+Serializer", x[0]), classes))
        serializer_class = serializer_classes[0][1]

        logger.debug("Found serializer class {serializer_class} for protocol {protocol_name}"
                     .format(serializer_class=serializer_class, protocol_name=protocol_name))
        serializer = serializer_class()

        config_loader = ConfigLoader("protocol-config_schema.json", ProtocolConfig)
        protocol_config = config_loader.load(open(Path(directory, "protocols", protocol_name, DEFAULT_PROTOCOL_CONFIG_FILE)))

        # instantiate the protocol manager.
        protocol = Protocol(protocol_name, serializer, protocol_config)
        self.register((protocol_name, None), protocol)
Ejemplo n.º 4
0
def _verify_ledger_apis_access() -> None:
    """Verify access to ledger apis."""
    path = Path(DEFAULT_AEA_CONFIG_FILE)
    agent_loader = ConfigLoader("aea-config_schema.json", AgentConfig)
    fp = open(str(path), mode="r", encoding="utf-8")
    aea_conf = agent_loader.load(fp)

    for identifier, value in aea_conf.ledger_apis.read_all():
        if identifier not in SUPPORTED_LEDGER_APIS:
            ValueError("Unsupported identifier in ledger apis.")

    fetchai_ledger_api_config = aea_conf.ledger_apis.read(FETCHAI)
    if fetchai_ledger_api_config is None:
        logger.debug("No fetchai ledger api config specified.")
    else:
        fetchai_ledger_api_config = cast(LedgerAPIConfig,
                                         fetchai_ledger_api_config)
        _try_to_instantiate_fetchai_ledger_api(fetchai_ledger_api_config.addr,
                                               fetchai_ledger_api_config.port)

    ethereum_ledger_config = aea_conf.ledger_apis.read(ETHEREUM)
    if ethereum_ledger_config is None:
        logger.debug("No ethereum ledger api config specified.")
    else:
        ethereum_ledger_config = cast(LedgerAPIConfig, ethereum_ledger_config)
        _try_to_instantiate_ethereum_ledger_api(ethereum_ledger_config.addr,
                                                ethereum_ledger_config.port)
Ejemplo n.º 5
0
def _load_protocol_specification_from_string(
    specification_content: str, ) -> ProtocolSpecification:
    """Load a protocol specification from string."""
    file = StringIO(initial_value=specification_content)
    config_loader = ConfigLoader("protocol-specification_schema.json",
                                 ProtocolSpecification)
    protocol_spec = config_loader.load_protocol_specification(file)
    return protocol_spec
Ejemplo n.º 6
0
 def dump_config(self) -> None:
     """Save agent config on the disc."""
     config_data = self.json
     self.agent_config.validate_config_data(
         config_data, env_vars_friendly=self.env_vars_friendly)
     with open_file(self.agent_config_file_path, "w") as file_pointer:
         ConfigLoader.from_configuration_type(PackageType.AGENT).dump(
             self.agent_config, file_pointer)
Ejemplo n.º 7
0
class Context(object):
    """A class to keep configuration of the cli tool."""

    agent_config: AgentConfig

    def __init__(self, cwd: str = "."):
        """Init the context."""
        self.config = dict()  # type: Dict
        self.agent_loader = ConfigLoader("aea-config_schema.json", AgentConfig)
        self.skill_loader = ConfigLoader("skill-config_schema.json",
                                         SkillConfig)
        self.connection_loader = ConfigLoader("connection-config_schema.json",
                                              ConnectionConfig)
        self.protocol_loader = ConfigLoader("protocol-config_schema.json",
                                            ProtocolConfig)
        self.cwd = cwd

    def set_config(self, key, value) -> None:
        """
        Set a config.

        :param key: the key for the configuration.
        :param value: the value associated with the key.
        :return: None
        """
        self.config[key] = value
        logger.debug('  config[%s] = %s' % (key, value))

    def get_dependencies(self) -> List[str]:
        """Aggregate the dependencies from every component.

        :return a list of dependency version specification. e.g. ["gym >= 1.0.0"]
        """
        dependencies = []  # type: List[str]
        for protocol_id in self.agent_config.protocols:
            path = str(
                Path("protocols", protocol_id, DEFAULT_PROTOCOL_CONFIG_FILE))
            protocol_config = self.protocol_loader.load(open(path))
            deps = cast(List[str], protocol_config.dependencies)
            dependencies.extend(deps)

        for connection_id in self.agent_config.connections:
            path = str(
                Path("connections", connection_id,
                     DEFAULT_CONNECTION_CONFIG_FILE))
            connection_config = self.connection_loader.load(open(path))
            deps = cast(List[str], connection_config.dependencies)
            dependencies.extend(deps)

        for skill_id in self.agent_config.skills:
            path = str(Path("skills", skill_id, DEFAULT_SKILL_CONFIG_FILE))
            skill_config = self.skill_loader.load(open(path))
            deps = cast(List[str], skill_config.dependencies)
            dependencies.extend(deps)

        return sorted(set(dependencies))
Ejemplo n.º 8
0
    def test_compare_latest_generator_output_with_test_protocol(self):
        """Test that the "t_protocol" test protocol matches with what the latest generator generates based on the specification."""
        # check protoc is installed
        res = shutil.which("protoc")
        if res is None:
            pytest.skip(
                "Please install protocol buffer first! See the following link: https://developers.google.com/protocol-buffers/"
            )

        # Specification
        protocol_name = "t_protocol"
        path_to_specification = os.path.join(self.cwd, "tests", "data",
                                             "sample_specification.yaml")
        path_to_generated_protocol = self.t
        path_to_original_protocol = os.path.join(self.cwd, "tests", "data",
                                                 "generator", protocol_name)
        path_to_package = "tests.data.generator."

        # Load the config
        config_loader = ConfigLoader("protocol-specification_schema.json",
                                     ProtocolSpecification)
        protocol_specification = config_loader.load_protocol_specification(
            open(path_to_specification))

        # Generate the protocol
        protocol_generator = ProtocolGenerator(
            protocol_specification,
            path_to_generated_protocol,
            path_to_protocol_package=path_to_package,
        )
        protocol_generator.generate()

        # Apply black
        try:
            subp = subprocess.Popen(  # nosec
                [
                    sys.executable,
                    "-m",
                    "black",
                    os.path.join(path_to_generated_protocol, protocol_name),
                    "--quiet",
                ])
            subp.wait(10.0)
        finally:
            poll = subp.poll()
            if poll is None:  # pragma: no cover
                subp.terminate()
                subp.wait(5)

        # compare __init__.py
        init_file_generated = Path(self.t, protocol_name, "__init__.py")
        init_file_original = Path(
            path_to_original_protocol,
            "__init__.py",
        )
        assert filecmp.cmp(init_file_generated, init_file_original)
Ejemplo n.º 9
0
 def __init__(self, cwd: str = "."):
     """Init the context."""
     self.config = dict()  # type: Dict
     self.agent_loader = ConfigLoader("aea-config_schema.json", AgentConfig)
     self.skill_loader = ConfigLoader("skill-config_schema.json",
                                      SkillConfig)
     self.connection_loader = ConfigLoader("connection-config_schema.json",
                                           ConnectionConfig)
     self.protocol_loader = ConfigLoader("protocol-config_schema.json",
                                         ProtocolConfig)
     self.cwd = cwd
Ejemplo n.º 10
0
def load_protocol_specification(specification_path: str) -> ProtocolSpecification:
    """
    Load a protocol specification.

    :param specification_path: path to the protocol specification yaml file.
    :return: A ProtocolSpecification object
    """
    config_loader = ConfigLoader(
        "protocol-specification_schema.json", ProtocolSpecification
    )
    protocol_spec = config_loader.load_protocol_specification(open(specification_path))
    return protocol_spec
Ejemplo n.º 11
0
    def from_dir(cls, directory: str, agent_context: AgentContext) -> 'Skill':
        """
        Load a skill from a directory.

        :param directory: the skill
        :param agent_context: the agent's context
        :return: the Skill object.
        :raises Exception: if the parsing failed.
        """
        # check if there is the config file. If not, then return None.
        skill_loader = ConfigLoader("skill-config_schema.json", SkillConfig)
        skill_config = skill_loader.load(open(os.path.join(directory, DEFAULT_SKILL_CONFIG_FILE)))
        skills_spec = importlib.util.spec_from_file_location(skill_config.name, os.path.join(directory, "__init__.py"))
        skill_module = importlib.util.module_from_spec(skills_spec)
        sys.modules[skill_config.name + "_skill"] = skill_module
        loader_contents = [path.name for path in Path(directory).iterdir()]
        skills_packages = list(filter(lambda x: not x.startswith("__"), loader_contents))  # type: ignore
        logger.debug("Processing the following skill package: {}".format(skills_packages))

        skill_context = SkillContext(agent_context)

        handlers_by_id = skill_config.handlers.read_all()
        if len(handlers_by_id) > 0:
            handlers_configurations = list(dict(handlers_by_id).values())
            handlers = Handler.parse_module(os.path.join(directory, "handlers.py"), handlers_configurations, skill_context)
        else:
            handlers = []

        behaviours_by_id = skill_config.behaviours.read_all()
        if len(behaviours_by_id) > 0:
            behaviours_configurations = list(dict(behaviours_by_id).values())
            behaviours = Behaviour.parse_module(os.path.join(directory, "behaviours.py"), behaviours_configurations, skill_context)
        else:
            behaviours = []

        tasks_by_id = skill_config.tasks.read_all()
        if len(tasks_by_id) > 0:
            tasks_configurations = list(dict(tasks_by_id).values())
            tasks = Task.parse_module(os.path.join(directory, "tasks.py"), tasks_configurations, skill_context)
        else:
            tasks = []

        shared_classes_by_id = skill_config.shared_classes.read_all()
        if len(shared_classes_by_id) > 0:
            shared_classes_configurations = list(dict(shared_classes_by_id).values())
            shared_classes_instances = SharedClass.parse_module(directory, shared_classes_configurations, skill_context)
        else:
            shared_classes_instances = []

        skill = Skill(skill_config, skill_context, handlers, behaviours, tasks, shared_classes_instances)
        skill_context._skill = skill

        return skill
Ejemplo n.º 12
0
def _verify_or_create_private_keys(aea_project_path: Path) -> None:
    """Verify or create private keys."""
    path_to_configuration = aea_project_path / DEFAULT_AEA_CONFIG_FILE
    agent_loader = ConfigLoader("aea-config_schema.json", AgentConfig)
    fp_read = path_to_configuration.open(mode="r", encoding="utf-8")
    agent_configuration = agent_loader.load(fp_read)

    for identifier, _value in agent_configuration.private_key_paths.read_all():
        if identifier not in SUPPORTED_CRYPTOS:
            ValueError("Unsupported identifier in private key paths.")

    fetchai_private_key_path = agent_configuration.private_key_paths.read(FETCHAI)
    if fetchai_private_key_path is None:
        _create_fetchai_private_key(
            private_key_file=str(aea_project_path / FETCHAI_PRIVATE_KEY_FILE)
        )
        agent_configuration.private_key_paths.update(FETCHAI, FETCHAI_PRIVATE_KEY_FILE)
    else:
        try:
            _try_validate_fet_private_key_path(
                str(aea_project_path / fetchai_private_key_path), exit_on_error=False
            )
        except FileNotFoundError:  # pragma: no cover
            logger.error(
                "File {} for private key {} not found.".format(
                    repr(fetchai_private_key_path), FETCHAI,
                )
            )
            raise

    ethereum_private_key_path = agent_configuration.private_key_paths.read(ETHEREUM)
    if ethereum_private_key_path is None:
        _create_ethereum_private_key(
            private_key_file=str(aea_project_path / ETHEREUM_PRIVATE_KEY_FILE)
        )
        agent_configuration.private_key_paths.update(
            ETHEREUM, ETHEREUM_PRIVATE_KEY_FILE
        )
    else:
        try:
            _try_validate_ethereum_private_key_path(
                str(aea_project_path / ethereum_private_key_path), exit_on_error=False
            )
        except FileNotFoundError:  # pragma: no cover
            logger.error(
                "File {} for private key {} not found.".format(
                    repr(ethereum_private_key_path), ETHEREUM,
                )
            )
            raise

    fp_write = path_to_configuration.open(mode="w", encoding="utf-8")
    agent_loader.dump(agent_configuration, fp_write)
Ejemplo n.º 13
0
    def from_dir(cls, directory: str, agent_context: AgentContext) -> "Skill":
        """
        Load a skill from a directory.

        :param directory: the skill directory.
        :param agent_context: the agent's context
        :return: the Skill object.
        :raises Exception: if the parsing failed.
        """
        # check if there is the config file. If not, then return None.
        skill_loader = ConfigLoader("skill-config_schema.json", SkillConfig)
        skill_config = skill_loader.load(
            open(os.path.join(directory, DEFAULT_SKILL_CONFIG_FILE)))
        skill_module = load_agent_component_package("skill", skill_config.name,
                                                    skill_config.author,
                                                    Path(directory))
        add_agent_component_module_to_sys_modules("skill", skill_config.name,
                                                  skill_config.author,
                                                  skill_module)
        loader_contents = [path.name for path in Path(directory).iterdir()]
        skills_packages = list(
            filter(lambda x: not x.startswith("__"),
                   loader_contents))  # type: ignore
        logger.debug("Processing the following skill package: {}".format(
            skills_packages))

        skill_context = SkillContext(agent_context)
        # set the logger of the skill context.
        logger_name = "aea.{}.skills.{}.{}".format(agent_context.agent_name,
                                                   skill_config.author,
                                                   skill_config.name)
        skill_context._logger = logging.getLogger(logger_name)

        handlers_by_id = dict(skill_config.handlers.read_all())
        handlers = Handler.parse_module(os.path.join(directory, "handlers.py"),
                                        handlers_by_id, skill_context)

        behaviours_by_id = dict(skill_config.behaviours.read_all())
        behaviours = Behaviour.parse_module(
            os.path.join(directory, "behaviours.py"),
            behaviours_by_id,
            skill_context,
        )

        models_by_id = dict(skill_config.models.read_all())
        model_instances = Model.parse_module(directory, models_by_id,
                                             skill_context)

        skill = Skill(skill_config, skill_context, handlers, behaviours,
                      model_instances)
        skill_context._skill = skill

        return skill
Ejemplo n.º 14
0
    def _add_protocol(
        self,
        protocol_directory: Path,
        allowed_protocols: Optional[Set[PublicId]] = None,
    ):
        """
        Add a protocol. If the protocol is not allowed, it is ignored.

        :param protocol_directory: the directory of the protocol to be added.
        :param allowed_protocols: an optional set of allowed protocols.
                                  If None, every protocol is allowed.
        :return: None
        """
        protocol_name = protocol_directory.name
        config_loader = ConfigLoader("protocol-config_schema.json",
                                     ProtocolConfig)
        protocol_config = config_loader.load(
            open(protocol_directory / DEFAULT_PROTOCOL_CONFIG_FILE))
        protocol_public_id = PublicId(protocol_config.author,
                                      protocol_config.name,
                                      protocol_config.version)
        if (allowed_protocols is not None
                and protocol_public_id not in allowed_protocols):
            logger.debug(
                "Ignoring protocol {}, not declared in the configuration file."
                .format(protocol_public_id))
            return

        # get the serializer
        serialization_spec = importlib.util.spec_from_file_location(
            "serialization", protocol_directory / "serialization.py")
        serialization_module = importlib.util.module_from_spec(
            serialization_spec)
        serialization_spec.loader.exec_module(
            serialization_module)  # type: ignore
        classes = inspect.getmembers(serialization_module, inspect.isclass)
        serializer_classes = list(
            filter(lambda x: re.match("\\w+Serializer", x[0]), classes))
        serializer_class = serializer_classes[0][1]

        logger.debug(
            "Found serializer class {serializer_class} for protocol {protocol_name}"
            .format(serializer_class=serializer_class,
                    protocol_name=protocol_name))
        serializer = serializer_class()

        # instantiate the protocol
        protocol = Protocol(protocol_config.public_id, serializer,
                            protocol_config)
        self.register(protocol_public_id, protocol)
Ejemplo n.º 15
0
def _verify_or_create_private_keys(ctx: Context) -> None:
    """
    Verify or create private keys.

    :param ctx: Context
    """
    path = Path(DEFAULT_AEA_CONFIG_FILE)
    agent_loader = ConfigLoader("aea-config_schema.json", AgentConfig)
    fp = path.open(mode="r", encoding="utf-8")
    aea_conf = agent_loader.load(fp)

    for identifier, _value in aea_conf.private_key_paths.read_all():
        if identifier not in SUPPORTED_CRYPTOS:
            ValueError("Unsupported identifier in private key paths.")

    fetchai_private_key_path = aea_conf.private_key_paths.read(FETCHAI)
    if fetchai_private_key_path is None:
        _create_fetchai_private_key()
        aea_conf.private_key_paths.update(FETCHAI, FETCHAI_PRIVATE_KEY_FILE)
    else:
        try:
            _try_validate_fet_private_key_path(fetchai_private_key_path)
        except FileNotFoundError:  # pragma: no cover
            logger.error("File {} for private key {} not found.".format(
                repr(fetchai_private_key_path),
                FETCHAI,
            ))
            sys.exit(1)

    ethereum_private_key_path = aea_conf.private_key_paths.read(ETHEREUM)
    if ethereum_private_key_path is None:
        _create_ethereum_private_key()
        aea_conf.private_key_paths.update(ETHEREUM, ETHEREUM_PRIVATE_KEY_FILE)
    else:
        try:
            _try_validate_ethereum_private_key_path(ethereum_private_key_path)
        except FileNotFoundError:  # pragma: no cover
            logger.error("File {} for private key {} not found.".format(
                repr(ethereum_private_key_path),
                ETHEREUM,
            ))
            sys.exit(1)

    # update aea config
    path = Path(DEFAULT_AEA_CONFIG_FILE)
    fp = path.open(mode="w", encoding="utf-8")
    agent_loader.dump(aea_conf, fp)
    ctx.agent_config = aea_conf
Ejemplo n.º 16
0
def fingerprint_package(package_dir: Path,
                        package_type: Union[str, PackageType]) -> None:
    """
    Fingerprint components of an item.

    :param ctx: the context.
    :param item_type: the item type.
    :param item_public_id: the item public id.
    :return: None
    """
    package_type = PackageType(package_type)
    item_type = str(package_type)
    default_config_file_name = _get_default_configuration_file_name_from_type(
        item_type)
    config_loader = ConfigLoader.from_configuration_type(item_type)
    config_file_path = Path(package_dir, default_config_file_name)
    config = config_loader.load(open_file(config_file_path))

    if not package_dir.exists():
        # we only permit non-vendorized packages to be fingerprinted
        raise ValueError("Package not found at path {}".format(package_dir))

    fingerprints_dict = _compute_fingerprint(
        package_dir, ignore_patterns=config.fingerprint_ignore_patterns
    )  # type: Dict[str, str]

    # Load item specification yaml file and add fingerprints
    config.fingerprint = fingerprints_dict
    config_loader.dump(config, open_file(config_file_path, "w"))
Ejemplo n.º 17
0
    def loader(self) -> ConfigLoader:
        """
        Create ConfigLoader for Agent config.

        :return: ConfigLoader for AgentConfig
        """
        return ConfigLoader.from_configuration_type(PackageType.AGENT)
Ejemplo n.º 18
0
def _run_interaction_channel():
    # load agent configuration file
    loader = ConfigLoader.from_configuration_type(PackageType.AGENT)
    agent_configuration = loader.load(Path(DEFAULT_AEA_CONFIG_FILE).open())
    agent_name = agent_configuration.name
    # load stub connection
    configuration = ConnectionConfig(
        input_file=DEFAULT_OUTPUT_FILE_NAME,
        output_file=DEFAULT_INPUT_FILE_NAME,
        connection_id=StubConnection.connection_id,
    )
    identity_stub = Identity(agent_name + "_interact", "interact")
    stub_connection = StubConnection(configuration=configuration,
                                     identity=identity_stub)
    multiplexer = Multiplexer([stub_connection])
    inbox = InBox(multiplexer)
    outbox = OutBox(multiplexer, default_address=identity_stub.address)
    dialogues = DefaultDialogues(identity_stub.name)

    try:
        multiplexer.connect()
        while True:  # pragma: no cover
            _process_envelopes(agent_name, identity_stub, inbox, outbox,
                               dialogues)

    except KeyboardInterrupt:
        click.echo("Interaction interrupted!")
    except BaseException as e:  # pylint: disable=broad-except # pragma: no cover
        click.echo(e)
    finally:
        multiplexer.disconnect()
Ejemplo n.º 19
0
 def test_agent_config_updated(self):
     """Test the agent configuration is updated."""
     loader = ConfigLoader.from_configuration_type(PackageType.AGENT)
     with Path(self._get_cwd(), DEFAULT_AEA_CONFIG_FILE).open() as fp:
         agent_config = loader.load(fp)
     assert DefaultMessage.protocol_id in agent_config.protocols
     assert ERROR_SKILL_PUBLIC_ID in agent_config.skills
Ejemplo n.º 20
0
def bump_version_in_yaml(configuration_file_path: Path, type_: str,
                         version: str) -> None:
    """Bump the package version in the package yaml."""
    loader = ConfigLoader.from_configuration_type(type_[:-1])
    config = loader.load(configuration_file_path.open())
    config.version = version
    loader.dump(config, open(configuration_file_path, "w"))
Ejemplo n.º 21
0
def _run_interaction_channel():
    loader = ConfigLoader.from_configuration_type(PackageType.AGENT)
    agent_configuration = loader.load(Path(DEFAULT_AEA_CONFIG_FILE).open())
    agent_name = agent_configuration.name

    identity_stub = Identity(agent_name + "_interact", "interact")
    _load_packages(identity_stub)

    # load agent configuration file
    from packages.fetchai.connections.stub.connection import (  # noqa: F811 # pylint: disable=import-outside-toplevel
        DEFAULT_INPUT_FILE_NAME,
        DEFAULT_OUTPUT_FILE_NAME,
        StubConnection,
    )
    from packages.fetchai.protocols.default.dialogues import (  # noqa: F811 # pylint: disable=import-outside-toplevel
        DefaultDialogue,
        DefaultDialogues,
    )
    from packages.fetchai.protocols.default.message import (  # noqa: F811 # pylint: disable=import-outside-toplevel
        DefaultMessage,
    )

    # load stub connection
    configuration = ConnectionConfig(
        input_file=DEFAULT_OUTPUT_FILE_NAME,
        output_file=DEFAULT_INPUT_FILE_NAME,
        connection_id=StubConnection.connection_id,
    )

    stub_connection = StubConnection(
        configuration=configuration, identity=identity_stub
    )
    multiplexer = Multiplexer([stub_connection])
    inbox = InBox(multiplexer)
    outbox = OutBox(multiplexer)

    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

        :param message: an incoming/outgoing first message
        :param receiver_address: the address of the receiving agent
        :return: The role of the agent
        """
        return DefaultDialogue.Role.AGENT

    dialogues = DefaultDialogues(identity_stub.name, role_from_first_message)

    try:
        multiplexer.connect()
        while True:  # pragma: no cover
            _process_envelopes(agent_name, inbox, outbox, dialogues, DefaultMessage)

    except KeyboardInterrupt:
        click.echo("Interaction interrupted!")
    except BaseException as e:  # pylint: disable=broad-except # pragma: no cover
        click.echo(e)
    finally:
        multiplexer.disconnect()
Ejemplo n.º 22
0
def _get_item_details(ctx, item_type) -> List[Dict]:
    """Return a list of item details, given the item type."""
    result = []
    item_type_plural = item_type + "s"
    public_ids = getattr(ctx.agent_config,
                         item_type_plural)  # type: Set[PublicId]
    default_file_name = _get_default_configuration_file_name_from_type(
        item_type)
    for public_id in public_ids:
        # first, try to retrieve the item from the vendor directory.
        configuration_filepath = Path(
            ctx.cwd,
            "vendor",
            public_id.author,
            item_type_plural,
            public_id.name,
            default_file_name,
        )
        # otherwise, if it does not exist, retrieve the item from the agent custom packages
        if not configuration_filepath.exists():
            configuration_filepath = Path(ctx.cwd, item_type_plural,
                                          public_id.name, default_file_name)
        configuration_loader = ConfigLoader.from_configuration_type(
            PackageType(item_type))
        details = retrieve_details(public_id.name, configuration_loader,
                                   str(configuration_filepath))
        result.append(details)
    return result
Ejemplo n.º 23
0
 def _load_agent_config(self) -> AgentConfig:
     """Load the agent configuration."""
     config_loader = ConfigLoader.from_configuration_type(
         ConfigurationType.AGENT)
     agent_config = config_loader.load(
         open(os.path.join(self.directory, DEFAULT_AEA_CONFIG_FILE)))
     return agent_config
Ejemplo n.º 24
0
def test_config_loader_dump():
    """Test ConfigLoader.dump"""
    config_loader = ConfigLoader.from_configuration_type(PackageType.PROTOCOL)
    configuration = MagicMock()
    with mock.patch.object(aea.configurations.loader, "yaml_dump"), mock.patch(
        "jsonschema.Draft4Validator.validate"
    ), mock.patch("builtins.open"):
        config_loader.dump(configuration, open("foo"))
Ejemplo n.º 25
0
def _add_item(click_context, item_type, item_public_id) -> None:
    """
    Add an item.

    :param click_context: the click context.
    :param item_type: the item type.
    :param item_public_id: the item public id.
    :return: None
    """
    ctx = cast(Context, click_context.obj)
    agent_name = cast(str, ctx.agent_config.agent_name)
    item_type_plural = item_type + "s"
    supported_items = getattr(ctx.agent_config, item_type_plural)

    is_local = ctx.config.get("is_local")

    click.echo("Adding {} '{}' to the agent '{}'...".format(
        item_type, item_public_id, agent_name))

    # check if we already have an item with the same name
    logger.debug("{} already supported by the agent: {}".format(
        item_type_plural.capitalize(), supported_items))
    if _is_item_present(item_type, item_public_id, ctx):
        logger.error("A {} with id '{}/{}' already exists. Aborting...".format(
            item_type, item_public_id.author, item_public_id.name))
        sys.exit(1)

    # find and add protocol
    if item_public_id in [DEFAULT_CONNECTION, DEFAULT_PROTOCOL, DEFAULT_SKILL]:
        package_path = _find_item_in_distribution(ctx, item_type,
                                                  item_public_id)
        _copy_package_directory(ctx, package_path, item_type,
                                item_public_id.name, item_public_id.author)
    elif is_local:
        package_path = _find_item_locally(ctx, item_type, item_public_id)
        _copy_package_directory(ctx, package_path, item_type,
                                item_public_id.name, item_public_id.author)
    else:
        package_path = fetch_package(item_type,
                                     public_id=item_public_id,
                                     cwd=ctx.cwd)
    if item_type in {"connection", "skill"}:
        configuration_file_name = _get_default_configuration_file_name_from_type(
            item_type)
        configuration_path = package_path / configuration_file_name
        configuration_loader = ConfigLoader.from_configuration_type(
            ConfigurationType(item_type))
        item_configuration = configuration_loader.load(
            configuration_path.open())
        _add_protocols(click_context, item_configuration.protocols)

    # add the item to the configurations.
    logger.debug("Registering the {} into {}".format(item_type,
                                                     DEFAULT_AEA_CONFIG_FILE))
    supported_items.add(item_public_id)
    ctx.agent_loader.dump(
        ctx.agent_config,
        open(os.path.join(ctx.cwd, DEFAULT_AEA_CONFIG_FILE), "w"))
Ejemplo n.º 26
0
def verify_or_create_private_keys(
    aea_project_path: Path,
    exit_on_error: bool = True,
) -> AgentConfig:
    """
    Verify or create private keys.

    :param ctx: Context
    """
    path_to_aea_config = aea_project_path / DEFAULT_AEA_CONFIG_FILE
    agent_loader = ConfigLoader("aea-config_schema.json", AgentConfig)
    fp = path_to_aea_config.open(mode="r", encoding="utf-8")
    aea_conf = agent_loader.load(fp)

    for identifier, _value in aea_conf.private_key_paths.read_all():
        if identifier not in crypto_registry.supported_ids:  # pragma: nocover
            ValueError("Unsupported identifier in private key paths.")

    for identifier, private_key_path in IDENTIFIER_TO_KEY_FILES.items():
        config_private_key_path = aea_conf.private_key_paths.read(identifier)
        if config_private_key_path is None:
            if identifier == aea_conf.default_ledger:  # pragma: nocover
                create_private_key(
                    identifier,
                    private_key_file=str(aea_project_path / private_key_path),
                )
                aea_conf.private_key_paths.update(identifier, private_key_path)
        else:
            try:
                try_validate_private_key_path(
                    identifier,
                    str(aea_project_path / private_key_path),
                    exit_on_error=exit_on_error,
                )
            except FileNotFoundError:  # pragma: no cover
                raise ValueError(
                    "File {} for private key {} not found.".format(
                        repr(private_key_path),
                        identifier,
                    ))

    # update aea config
    fp = path_to_aea_config.open(mode="w", encoding="utf-8")
    agent_loader.dump(aea_conf, fp)
    return aea_conf
Ejemplo n.º 27
0
def retrieve_details(name: str, loader: ConfigLoader, config_filepath: str):
    """Return description of a protocol, skill or connection."""
    config = loader.load(open(str(config_filepath)))
    assert config.name == name
    return {
        "name": config.name,
        "description": config.description,
        "version": config.version
    }
Ejemplo n.º 28
0
def test_config_loader_dump_agent_config():
    """Test ConfigLoader.dump"""
    config_loader = ConfigLoader.from_configuration_type(PackageType.AGENT)
    configuration = MagicMock(ordered_json={"component_configurations": []})
    with mock.patch.object(aea.configurations.loader,
                           "yaml_dump_all"), mock.patch.object(
                               ConfigValidator,
                               "_validate"), mock.patch("builtins.open"):
        config_loader.dump(configuration, open("foo"))
Ejemplo n.º 29
0
    def populate_skills(
        self,
        directory: str,
        agent_context: AgentContext,
        allowed_skills: Optional[Set[PublicId]] = None,
    ) -> None:
        """
        Populate skills.

        :param directory: the agent's resources directory.
        :param agent_context: the agent's context object
        :param allowed_skills: an optional set of allowed skills (public ids).
                               If None, every skill is allowed.
        :return: None
        """
        skill_directory_paths = set()  # type: ignore

        # find all skill directories from vendor/*/skills
        skill_directory_paths.update(
            Path(directory, "vendor").glob("./*/skills/*/"))
        # find all skill directories from skills/
        skill_directory_paths.update(Path(directory, "skills").glob("./*/"))

        skills_packages_paths = list(
            filter(
                lambda x: PACKAGE_NAME_REGEX.match(str(x.name)) and x.is_dir(),
                skill_directory_paths,
            ))  # type: ignore
        logger.debug("Found the following skill packages: {}".format(
            pprint.pformat(map(str, skills_packages_paths))))
        for skill_directory in skills_packages_paths:
            logger.debug(
                "Processing the following skill directory: '{}".format(
                    skill_directory))
            try:
                skill_loader = ConfigLoader.from_configuration_type(
                    ConfigurationType.SKILL)
                skill_config = skill_loader.load(
                    open(skill_directory / DEFAULT_SKILL_CONFIG_FILE))
                if (allowed_skills is not None
                        and skill_config.public_id not in allowed_skills):
                    logger.debug(
                        "Ignoring skill {}, not declared in the configuration file."
                        .format(skill_config.public_id))
                    continue
                else:
                    skill = Skill.from_dir(str(skill_directory), agent_context)
                    assert skill is not None
                    self.add_skill(skill)
            except Exception as e:
                logger.warning(
                    "A problem occurred while parsing the skill directory {}. Exception: {}"
                    .format(skill_directory, str(e)))
Ejemplo n.º 30
0
    def from_dir(cls, directory: str, agent_context: AgentContext) -> Optional['Skill']:
        """
        Load a skill from a directory.

        :param directory: the skill
        :param agent_context: the agent's context
        :return: the Skill object. None if the parsing failed.
        """
        # check if there is the config file. If not, then return None.
        skill_loader = ConfigLoader("skill-config_schema.json", SkillConfig)
        skill_config = skill_loader.load(open(os.path.join(directory, DEFAULT_SKILL_CONFIG_FILE)))
        if skill_config is None:
            return None

        skills_spec = importlib.util.spec_from_file_location(skill_config.name, os.path.join(directory, "__init__.py"))
        if skills_spec is None:
            logger.warning("No skill found.")
            return None

        skill_module = importlib.util.module_from_spec(skills_spec)
        sys.modules[skill_config.name + "_skill"] = skill_module
        skills_packages = list(filter(lambda x: not x.startswith("__"), skills_spec.loader.contents()))  # type: ignore
        logger.debug("Processing the following skill package: {}".format(skills_packages))

        skill_context = SkillContext(agent_context)

        handlers_configurations = list(dict(skill_config.handlers.read_all()).values())
        handlers = Handler.parse_module(os.path.join(directory, "handlers.py"), handlers_configurations, skill_context)
        behaviours_configurations = list(dict(skill_config.behaviours.read_all()).values())
        behaviours = Behaviour.parse_module(os.path.join(directory, "behaviours.py"), behaviours_configurations, skill_context)
        tasks_configurations = list(dict(skill_config.tasks.read_all()).values())
        tasks = Task.parse_module(os.path.join(directory, "tasks.py"), tasks_configurations, skill_context)
        shared_classes_configurations = list(dict(skill_config.shared_classes.read_all()).values())
        shared_classes_instances = SharedClass.parse_module(directory, shared_classes_configurations, skill_context)

        skill = Skill(skill_config, skill_context, handlers, behaviours, tasks, shared_classes_instances)
        skill_context._skill = skill

        return skill