Ejemplo n.º 1
0
def skill(click_context, skill_name):
    """Add a skill to the agent."""
    ctx = cast(Context, click_context.obj)
    agent_name = ctx.agent_config.agent_name

    is_registry = ctx.config.get("is_registry")
    if is_registry:
        public_id = str(skill_name)
        skill_name = split_public_id(skill_name)[1]

    logger.info("Adding skill '{}' to the agent '{}'...".format(skill_name, agent_name))

    # check if we already have a skill with the same name
    logger.debug("Skills already supported by the agent: {}".format(ctx.agent_config.skills))
    if skill_name in ctx.agent_config.skills:
        logger.error("A skill with name '{}' already exists. Aborting...".format(skill_name))
        sys.exit(1)

    # find and add protocol
    if is_registry:
        # fetch from Registry
        fetch_package('skill', public_id=public_id, cwd=ctx.cwd)
    else:
        _find_skill_locally(ctx, skill_name, click_context)

    # make the 'skills' folder a Python package.
    skills_init_module = os.path.join(ctx.cwd, "skills", "__init__.py")
    logger.debug("Creating {}".format(skills_init_module))
    Path(skills_init_module).touch(exist_ok=True)

    # add the skill to the configurations.
    logger.debug("Registering the skill into {}".format(DEFAULT_AEA_CONFIG_FILE))
    ctx.agent_config.skills.add(skill_name)
    ctx.agent_loader.dump(ctx.agent_config, open(os.path.join(ctx.cwd, DEFAULT_AEA_CONFIG_FILE), "w"))
Ejemplo n.º 2
0
def _install_dependency(dependency_name: str, dependency: Dependency):
    click.echo("Installing {}...".format(pprint.pformat(dependency_name)))
    try:
        index = dependency.get("index", None)
        git_url = dependency.get("git", None)
        revision = dependency.get("ref", "")
        version_constraint = dependency.get("version", "")
        command = [sys.executable, "-m", "pip", "install"]
        if git_url is not None:
            command += ["-i", index] if index is not None else []
            command += [
                "git+" + git_url + "@" + revision + "#egg=" + dependency_name
            ]
        else:
            command += ["-i", index] if index is not None else []
            command += [dependency_name + version_constraint]
        logger.debug("Calling '{}'".format(" ".join(command)))
        return_code = _try_install(command)
        if return_code == 1:
            # try a second time
            return_code = _try_install(command)
        assert return_code == 0
    except Exception as e:
        logger.error("An error occurred while installing {}, {}: {}".format(
            dependency_name, dependency, str(e)))
        sys.exit(1)
Ejemplo n.º 3
0
def delete(ctx: Context, agent_name):
    """Delete an agent."""
    path = Path(agent_name)

    # check that the target folder is an AEA project.
    cwd = os.getcwd()
    try:
        os.chdir(agent_name)
        fp = open(DEFAULT_AEA_CONFIG_FILE, mode="r", encoding="utf-8")
        ctx.agent_config = ctx.agent_loader.load(fp)
        _try_to_load_agent_config(ctx)
    except Exception:
        logger.error("The name provided is not an AEA project.")
        sys.exit(1)
    finally:
        os.chdir(cwd)

    logger.info("Deleting agent project directory '/{}'...".format(path))

    # delete the agent's directory
    try:
        shutil.rmtree(path, ignore_errors=False)
    except OSError:
        logger.error(
            "An error occurred while deleting the agent directory. Aborting..."
        )
        sys.exit(1)
Ejemplo n.º 4
0
def _try_to_load_required_protocols(ctx: Context):
    for protocol_public_id in ctx.agent_config.protocols:
        protocol_name = protocol_public_id.name
        protocol_author = protocol_public_id.author
        logger.debug("Processing protocol {}".format(protocol_public_id))
        protocol_dir = Path("vendor", protocol_public_id.author, "protocols",
                            protocol_name)
        if not protocol_dir.exists():
            protocol_dir = Path("protocols", protocol_name)

        try:
            ctx.protocol_loader.load(
                open(protocol_dir / DEFAULT_PROTOCOL_CONFIG_FILE))
        except FileNotFoundError:
            logger.error(
                "Protocol configuration file for protocol {} not found.".
                format(protocol_name))
            sys.exit(1)

        try:
            protocol_package = load_agent_component_package(
                "protocol", protocol_name, protocol_author, protocol_dir)
            add_agent_component_module_to_sys_modules("protocol",
                                                      protocol_name,
                                                      protocol_author,
                                                      protocol_package)
        except Exception:
            logger.error(
                "A problem occurred while processing protocol {}.".format(
                    protocol_public_id))
            sys.exit(1)
Ejemplo n.º 5
0
def protocol(ctx: Context, protocol_name):
    """Remove a protocol from the agent."""
    agent_name = ctx.agent_config.agent_name
    logger.info(
        "Removing protocol {protocol_name} from the agent {agent_name}...".
        format(agent_name=agent_name, protocol_name=protocol_name))

    if protocol_name not in ctx.agent_config.protocols:
        logger.error("Protocol '{}' not found.".format(protocol_name))
        exit(-1)

    protocol_folder = os.path.join("protocols", protocol_name)
    try:
        shutil.rmtree(protocol_folder)
    except BaseException:
        logger.exception("An error occurred.")
        exit(-1)

    # removing the protocol to the configurations.
    logger.debug(
        "Removing the protocol from {}".format(DEFAULT_AEA_CONFIG_FILE))
    if protocol_name in ctx.agent_config.protocols:
        ctx.agent_config.protocols.remove(protocol_name)
        ctx.agent_loader.dump(ctx.agent_config,
                              open(DEFAULT_AEA_CONFIG_FILE, "w"))
Ejemplo n.º 6
0
def install(ctx: Context, requirement: Optional[str]):
    """Install the dependencies."""
    _try_to_load_agent_config(ctx)

    if requirement:
        logger.debug(
            "Installing the dependencies in '{}'...".format(requirement))
        dependencies = list(
            map(lambda x: x.strip(),
                open(requirement).readlines()))
    else:
        logger.debug("Installing all the dependencies...")
        dependencies = ctx.get_dependencies()

    for d in dependencies:
        logger.info("Installing {}...".format(d))
        try:
            subp = subprocess.Popen(
                [sys.executable, "-m", "pip", "install", d])
            subp.wait(30.0)
            assert subp.returncode == 0
        except Exception:
            logger.error(
                "An error occurred while installing {}. Stopping...".format(d))
            sys.exit(1)
Ejemplo n.º 7
0
def connection(ctx: Context, connection_name):
    """Remove a connection from the agent."""
    agent_name = ctx.agent_config.agent_name
    logger.info(
        "Removing connection {connection_name} from the agent {agent_name}...".
        format(agent_name=agent_name, connection_name=connection_name))

    if connection_name not in ctx.agent_config.connections:
        logger.error("Connection '{}' not found.".format(connection_name))
        exit(-1)

    connection_folder = os.path.join("connections", connection_name)
    try:
        shutil.rmtree(connection_folder)
    except BaseException:
        logger.exception(
            "An error occurred while deleting '{}'.".format(connection_folder))
        exit(-1)

    # removing the connection to the configurations.
    logger.debug(
        "Removing the connection from {}".format(DEFAULT_AEA_CONFIG_FILE))
    if connection_name in ctx.agent_config.connections:
        ctx.agent_config.connections.remove(connection_name)
        ctx.agent_loader.dump(ctx.agent_config,
                              open(DEFAULT_AEA_CONFIG_FILE, "w"))
Ejemplo n.º 8
0
def connection(click_context, connection_name):
    """Add a connection to the configuration file."""
    ctx = cast(Context, click_context.obj)
    agent_name = ctx.agent_config.agent_name

    is_registry = ctx.config.get("is_registry")
    if is_registry:
        public_id = str(connection_name)
        connection_name = split_public_id(connection_name)[1]

    logger.info("Adding connection '{}' to the agent '{}'...".format(connection_name, agent_name))

    # check if we already have a connection with the same name
    logger.debug("Connections already supported by the agent: {}".format(ctx.agent_config.connections))
    if connection_name in ctx.agent_config.connections:
        logger.error("A connection with name '{}' already exists. Aborting...".format(connection_name))
        sys.exit(1)

    # find and add connection
    if is_registry:
        # fetch from Registry
        fetch_package('connection', public_id=public_id, cwd=ctx.cwd)
    else:
        _find_connection_locally(ctx, connection_name)

    # make the 'connections' folder a Python package.
    connections_init_module = os.path.join(ctx.cwd, "connections", "__init__.py")
    logger.debug("Creating {}".format(connections_init_module))
    Path(connections_init_module).touch(exist_ok=True)

    # add the connections to the configurations.
    logger.debug("Registering the connection into {}".format(DEFAULT_AEA_CONFIG_FILE))
    ctx.agent_config.connections.add(connection_name)
    ctx.agent_loader.dump(ctx.agent_config, open(os.path.join(ctx.cwd, DEFAULT_AEA_CONFIG_FILE), "w"))
Ejemplo n.º 9
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.º 10
0
def _try_add_key(ctx, type_, filepath):
    try:
        ctx.agent_config.private_key_paths.create(type_, filepath)
    except ValueError as e:  # pragma: no cover
        logger.error(str(e))
        sys.exit(1)
    ctx.agent_loader.dump(
        ctx.agent_config,
        open(os.path.join(ctx.cwd, DEFAULT_AEA_CONFIG_FILE), "w"))
Ejemplo n.º 11
0
def _try_get_balance(agent_config, wallet, type_):
    try:
        ledger_apis = LedgerApis(agent_config.ledger_apis_dict,
                                 agent_config.default_ledger)

        address = wallet.addresses[type_]
        return ledger_apis.token_balance(type_, address)
    except (AssertionError, ValueError) as e:  # pragma: no cover
        logger.error(str(e))
        sys.exit(1)
Ejemplo n.º 12
0
def _remove_item(ctx: Context, item_type, item_id: PublicId):
    """Remove an item from the configuration file and agent, given the public id."""
    item_name = item_id.name
    item_type_plural = "{}s".format(item_type)
    existing_item_ids = getattr(ctx.agent_config, item_type_plural)
    existing_items_name_to_ids = {
        public_id.name: public_id for public_id in existing_item_ids
    }

    agent_name = ctx.agent_config.agent_name
    click.echo(
        "Removing {item_type} '{item_name}' from the agent '{agent_name}'...".format(
            agent_name=agent_name, item_type=item_type, item_name=item_name
        )
    )

    if (
        item_id not in existing_items_name_to_ids.keys()
        and item_id not in existing_item_ids
    ):
        logger.error("The {} '{}' is not supported.".format(item_type, item_id))
        sys.exit(1)

    # TODO we assume the item in the agent config are necessarily in the agent projects.
    item_folder = Path("vendor", item_id.author, item_type_plural, item_name)
    if not item_folder.exists():
        # check if it is present in custom packages.
        item_folder = Path(item_type_plural, item_name)
        if not item_folder.exists():
            raise click.ClickException(
                "{} {} not found. Aborting.".format(item_type.title(), item_name)
            )
        elif (
            item_folder.exists() and not ctx.agent_config.author == item_id.author
        ):  # pragma: no cover
            raise click.ClickException(
                "{} {} author is different from {} agent author. "
                "Please fix the author field.".format(item_name, item_type, agent_name)
            )
        else:
            logger.debug(
                "Removing local {} {}.".format(item_type, item_name)
            )  # pragma: no cover

    try:
        shutil.rmtree(item_folder)
    except BaseException:
        logger.exception("An error occurred.")
        sys.exit(1)

    # removing the protocol to the configurations.
    item_public_id = existing_items_name_to_ids[item_name]
    logger.debug("Removing the {} from {}".format(item_type, DEFAULT_AEA_CONFIG_FILE))
    existing_item_ids.remove(item_public_id)
    ctx.agent_loader.dump(ctx.agent_config, open(DEFAULT_AEA_CONFIG_FILE, "w"))
Ejemplo n.º 13
0
def delete(ctx: Context, agent_name):
    """Delete an agent."""
    path = Path(agent_name)
    logger.info("Deleting agent's directory in '{}'...".format(path))

    # delete the agent's directory
    try:
        shutil.rmtree(path, ignore_errors=False)
    except OSError:
        logger.error("An error occurred while deleting the agent directory. Aborting...")
        exit(-1)
Ejemplo n.º 14
0
def run(click_context, connection_names: List[str], env_file: str,
        install_deps: bool):
    """Run the agent."""
    ctx = cast(Context, click_context.obj)
    _try_to_load_agent_config(ctx)
    _load_env_file(env_file)
    agent_name = cast(str, ctx.agent_config.agent_name)

    _verify_or_create_private_keys(ctx)
    _verify_ledger_apis_access()
    private_key_paths = dict([(identifier, config.path)
                              for identifier, config in
                              ctx.agent_config.private_key_paths.read_all()])
    ledger_api_configs = dict([
        (identifier, (config.addr, config.port))
        for identifier, config in ctx.agent_config.ledger_apis.read_all()
    ])

    wallet = Wallet(private_key_paths)
    ledger_apis = LedgerApis(ledger_api_configs)

    connection_names = [ctx.agent_config.default_connection
                        ] if connection_names is None else connection_names
    connections = []
    _try_to_load_protocols(ctx)
    try:
        for connection_name in connection_names:
            connection = _setup_connection(connection_name,
                                           wallet.public_keys[FETCHAI], ctx)
            connections.append(connection)
    except AEAConfigException as e:
        logger.error(str(e))
        sys.exit(1)

    if install_deps:
        if Path("requirements.txt").exists():
            click_context.invoke(install, requirement="requirements.txt")
        else:
            click_context.invoke(install)

    agent = AEA(agent_name,
                connections,
                wallet,
                ledger_apis,
                resources=Resources(str(Path("."))))
    try:
        agent.start()
    except KeyboardInterrupt:
        logger.info("Interrupted.")  # pragma: no cover
    except Exception as e:
        logger.exception(e)
        sys.exit(1)
    finally:
        agent.stop()
Ejemplo n.º 15
0
def add_key(ctx: Context, type_, file):
    """Add a private key to the wallet."""
    _try_to_load_agent_config(ctx)
    _validate_private_key_path(file, type_)
    try:
        ctx.agent_config.private_key_paths.create(
            type_, PrivateKeyPathConfig(type_, file))
    except ValueError as e:  # pragma: no cover
        logger.error(str(e))  # pragma: no cover
    ctx.agent_loader.dump(
        ctx.agent_config,
        open(os.path.join(ctx.cwd, DEFAULT_AEA_CONFIG_FILE), "w"))
Ejemplo n.º 16
0
def delete(click_context, agent_name):
    """Delete an agent."""
    click.echo("Deleting AEA project directory './{}'...".format(agent_name))

    # delete the agent's directory
    try:
        shutil.rmtree(agent_name, ignore_errors=False)
    except OSError:
        logger.error(
            "An error occurred while deleting the agent directory. Aborting..."
        )
        sys.exit(1)
Ejemplo n.º 17
0
def _try_get_address(ctx, type_):
    private_key_paths = {
        config_pair[0]: config_pair[1]
        for config_pair in ctx.agent_config.private_key_paths.read_all()
    }
    try:
        wallet = Wallet(private_key_paths)
        address = wallet.addresses[type_]
        return address
    except ValueError as e:  # pragma: no cover
        logger.error(str(e))
        sys.exit(1)
Ejemplo n.º 18
0
def _build_aea(connection_ids: Optional[List[PublicId]],
               skip_consistency_check: bool) -> AEA:
    try:
        builder = AEABuilder.from_aea_project(
            Path("."), skip_consistency_check=skip_consistency_check)
        aea = builder.build(connection_ids=connection_ids)
        return aea
    except Exception as e:
        # TODO use an ad-hoc exception class for predictable errors
        #      all the other exceptions should be logged with logger.exception
        logger.error(str(e))
        sys.exit(1)
Ejemplo n.º 19
0
def _build_aea(ctx: Context, connection_ids: List[PublicId]) -> AEA:
    """
    Build the aea.

    :param ctx: the context
    :param connection_ids: the list of connection ids
    """
    agent_name = cast(str, ctx.agent_config.agent_name)

    wallet = Wallet(ctx.agent_config.private_key_paths_dict)

    if len(wallet.addresses) > 1:
        identity = Identity(
            agent_name,
            addresses=wallet.addresses,
            default_address_key=ctx.agent_config.default_ledger,
        )
    else:  # pragma: no cover
        identity = Identity(
            agent_name,
            address=wallet.addresses[ctx.agent_config.default_ledger],
        )

    ledger_apis = LedgerApis(ctx.agent_config.ledger_apis_dict,
                             ctx.agent_config.default_ledger)

    default_connection_id = PublicId.from_str(
        ctx.agent_config.default_connection)
    connection_ids = ([default_connection_id]
                      if connection_ids is None else connection_ids)
    connections = []
    try:
        for connection_id in connection_ids:
            connection = _setup_connection(connection_id, identity.address,
                                           ctx)
            connections.append(connection)
    except AEAConfigException as e:
        logger.error(str(e))
        sys.exit(1)

    resources = Resources(AEA_DIR)

    aea = AEA(
        identity,
        connections,
        wallet,
        ledger_apis,
        resources,
        is_programmatic=False,
    )
    return aea
Ejemplo n.º 20
0
def _install_from_requirement(file: str):
    try:
        subp = subprocess.Popen(  # nosec
            [sys.executable, "-m", "pip", "install", "-r", file])  # nosec
        subp.wait(30.0)
        assert subp.returncode == 0
    except Exception:
        logger.error(
            "An error occurred while installing requirement file {}. Stopping..."
            .format(file))
        sys.exit(1)
    finally:
        poll = subp.poll()
        if poll is None:  # pragma: no cover
            subp.terminate()
            subp.wait(2)
Ejemplo n.º 21
0
def create(click_context, agent_name):
    """Create an agent."""
    ctx = cast(Context, click_context.obj)
    path = Path(agent_name)
    logger.info("Initializing AEA project '{}'".format(agent_name))
    logger.info("Creating project directory '/{}'".format(agent_name))

    # create the agent's directory
    try:
        path.mkdir(exist_ok=False)

        # create a config file inside it
        logger.info("Creating config file {}".format(DEFAULT_AEA_CONFIG_FILE))
        config_file = open(os.path.join(agent_name, DEFAULT_AEA_CONFIG_FILE),
                           "w")
        agent_config = AgentConfig(agent_name=agent_name,
                                   aea_version=aea.__version__,
                                   authors="",
                                   version="v1",
                                   license="",
                                   url="",
                                   registry_path=DEFAULT_REGISTRY_PATH,
                                   description="")
        agent_config.default_connection = DEFAULT_CONNECTION
        ctx.agent_loader.dump(agent_config, config_file)

        # next commands must be done from the agent's directory -> overwrite ctx.cwd
        ctx.agent_config = agent_config
        ctx.cwd = agent_config.agent_name

        logger.info("Default connections:")
        click_context.invoke(connection, connection_name=DEFAULT_CONNECTION)

        logger.info("Default skills:")
        click_context.invoke(skill, skill_name=DEFAULT_SKILL)

    except OSError:
        logger.error("Directory already exist. Aborting...")
        sys.exit(1)
    except ValidationError as e:
        logger.error(str(e))
        shutil.rmtree(agent_name, ignore_errors=True)
        sys.exit(1)
    except Exception as e:
        logger.exception(e)
        shutil.rmtree(agent_name, ignore_errors=True)
        sys.exit(1)
Ejemplo n.º 22
0
def skill(click_context, skill_name):
    """Add a skill to the agent."""
    ctx = cast(Context, click_context.obj)
    agent_name = ctx.agent_config.agent_name
    logger.debug("Adding skill {} to the agent {}...".format(skill_name, agent_name))

    # check if we already have a skill with the same name
    logger.debug("Skills already supported by the agent: {}".format(ctx.agent_config.skills))
    if skill_name in ctx.agent_config.skills:
        logger.error("A skill with name '{}' already exists. Aborting...".format(skill_name))
        exit(-1)

    # check that the provided path points to a proper skill directory -> look for skill.yaml file.
    # first check in aea dir
    registry_path = ctx.agent_config.registry_path
    skill_configuration_filepath = Path(os.path.join(registry_path, "skills", skill_name, DEFAULT_SKILL_CONFIG_FILE))
    if not skill_configuration_filepath.exists():
        # then check in registry
        registry_path = AEA_DIR
        skill_configuration_filepath = Path(os.path.join(registry_path, "skills", skill_name, DEFAULT_SKILL_CONFIG_FILE))
        if not skill_configuration_filepath.exists():
            logger.error("Cannot find skill: '{}'.".format(skill_name))
            exit(-1)

    # try to load the skill configuration file
    try:
        skill_configuration = ctx.skill_loader.load(open(str(skill_configuration_filepath)))
    except ValidationError as e:
        logger.error("Skill configuration file not valid: {}".format(str(e)))
        exit(-1)

    # copy the skill package into the agent's supported skills.
    src = str(Path(os.path.join(registry_path, "skills", skill_name)).absolute())
    dest = os.path.join(ctx.cwd, "skills", skill_name)
    logger.info("Copying skill modules. src={} dst={}".format(src, dest))
    try:
        shutil.copytree(src, dest)
    except Exception as e:
        logger.error(str(e))
        exit(-1)

    # make the 'skills' folder a Python package.
    skills_init_module = os.path.join(ctx.cwd, "skills", "__init__.py")
    logger.debug("Creating {}".format(skills_init_module))
    Path(skills_init_module).touch(exist_ok=True)

    # check for not supported protocol, and add it.
    for protocol_name in skill_configuration.protocols:
        if protocol_name not in ctx.agent_config.protocols:
            logger.info("Adding protocol '{}' to the agent...".format(protocol_name))
            click_context.invoke(protocol, protocol_name=protocol_name)

    # add the skill to the configurations.
    logger.debug("Registering the skill into {}".format(DEFAULT_AEA_CONFIG_FILE))
    ctx.agent_config.skills.add(skill_name)
    ctx.agent_loader.dump(ctx.agent_config, open(os.path.join(ctx.cwd, DEFAULT_AEA_CONFIG_FILE), "w"))
Ejemplo n.º 23
0
def set(ctx: Context, json_path: List[str], value, type):
    """Set a field."""
    type_ = from_string_to_type[type]
    config_loader = cast(ConfigLoader, ctx.config.get("configuration_loader"))
    configuration_file_path = cast(str,
                                   ctx.config.get("configuration_file_path"))

    configuration_dict = yaml.safe_load(open(configuration_file_path))
    config_loader.validator.validate(instance=configuration_dict)

    parent_object_path = json_path[:-1]
    attribute_name = json_path[-1]
    try:
        parent_object = _get_parent_object(configuration_dict,
                                           parent_object_path)
    except ValueError as e:
        logger.error(str(e))
        sys.exit(1)

    if attribute_name not in parent_object:
        logger.error("Attribute '{}' not found.".format(attribute_name))
        sys.exit(1)
    if not isinstance(parent_object.get(attribute_name),
                      (str, int, bool, float)):
        logger.error(
            "Attribute '{}' is not of primitive type.".format(attribute_name))
        sys.exit(1)

    try:
        if type_ != bool:
            parent_object[attribute_name] = type_(value)
        else:
            parent_object[attribute_name] = value not in FALSE_EQUIVALENTS
    except ValueError:  # pragma: no cover
        logger.error("Cannot convert {} to type {}".format(value, type_))

    try:
        configuration_obj = config_loader.configuration_type.from_json(
            configuration_dict)
        config_loader.validator.validate(instance=configuration_obj.json)
        config_loader.dump(configuration_obj, open(configuration_file_path,
                                                   "w"))
    except Exception:
        logger.error("Attribute or value not valid.")
        sys.exit(1)
Ejemplo n.º 24
0
def run(ctx: Context, connection_name: str):
    """Run the agent."""
    _try_to_load_agent_config(ctx)
    agent_name = cast(str, ctx.agent_config.agent_name)
    private_key_pem_path = cast(str, ctx.agent_config.private_key_pem_path)
    if private_key_pem_path == "":
        private_key_pem_path = _create_temporary_private_key_pem_path()
    else:
        _try_validate_private_key_pem_path(private_key_pem_path)
    crypto = Crypto(private_key_pem_path=private_key_pem_path)
    public_key = crypto.public_key
    connection_name = ctx.agent_config.default_connection if connection_name is None else connection_name
    _try_to_load_protocols(ctx)
    try:
        connection = _setup_connection(connection_name, public_key, ctx)
    except AEAConfigException as e:
        logger.error(str(e))
        exit(-1)
        return

    logger.debug("Installing all the dependencies...")
    for d in ctx.get_dependencies():
        logger.debug("Installing {}...".format(d))
        try:
            subp = subprocess.Popen(
                [sys.executable, "-m", "pip", "install", d])
            subp.wait(30.0)
        except Exception:
            logger.error(
                "An error occurred while installing {}. Stopping...".format(d))
            exit(-1)

    mailbox = MailBox(connection)
    agent = AEA(agent_name,
                mailbox,
                private_key_pem_path=private_key_pem_path,
                directory=str(Path(".")))
    try:
        agent.start()
    except KeyboardInterrupt:
        logger.info("Interrupted.")
    except Exception as e:
        logger.exception(e)
    finally:
        agent.stop()
Ejemplo n.º 25
0
def _try_generate_wealth(ctx, type_, sync):
    private_key_paths = {
        config_pair[0]: config_pair[1]
        for config_pair in ctx.agent_config.private_key_paths.read_all()
    }
    wallet = Wallet(private_key_paths)
    try:
        address = wallet.addresses[type_]
        testnet = TESTNETS[type_]
        click.echo(
            "Requesting funds for address {} on test network '{}'".format(
                address, testnet))
        _try_generate_testnet_wealth(type_, address)
        if sync:
            _wait_funds_release(ctx.agent_config, wallet, type_)

    except (AssertionError, ValueError) as e:  # pragma: no cover
        logger.error(str(e))
        sys.exit(1)
Ejemplo n.º 26
0
def protocol(click_context, protocol_name):
    """Add a protocol to the agent."""
    ctx = cast(Context, click_context.obj)
    agent_name = cast(str, ctx.agent_config.agent_name)
    logger.debug("Adding protocol {} to the agent {}...".format(protocol_name, agent_name))

    # check if we already have a protocol with the same name
    logger.debug("Protocols already supported by the agent: {}".format(ctx.agent_config.protocols))
    if protocol_name in ctx.agent_config.protocols:
        logger.error("A protocol with name '{}' already exists. Aborting...".format(protocol_name))
        exit(-1)

    # check that the provided path points to a proper protocol directory -> look for protocol.yaml file.
    # first check in aea dir
    registry_path = ctx.agent_config.registry_path
    protocol_configuration_filepath = Path(os.path.join(registry_path, "protocols", protocol_name, DEFAULT_PROTOCOL_CONFIG_FILE))
    if not protocol_configuration_filepath.exists():
        # then check in registry
        registry_path = AEA_DIR
        protocol_configuration_filepath = Path(os.path.join(registry_path, "protocols", protocol_name, DEFAULT_PROTOCOL_CONFIG_FILE))
        if not protocol_configuration_filepath.exists():
            logger.error("Cannot find protocol: '{}'.".format(protocol_name))
            exit(-1)

    # try to load the protocol configuration file
    try:
        protocol_configuration = ctx.protocol_loader.load(open(str(protocol_configuration_filepath)))
        logger.info("Protocol available: {}".format(protocol_configuration.name))
    except ValidationError as e:
        logger.error("Protocol configuration file not valid: {}".format(str(e)))
        exit(-1)
        return

    # copy the protocol package into the agent's supported connections.
    src = str(Path(os.path.join(registry_path, "protocols", protocol_name)).absolute())
    dest = os.path.join(ctx.cwd, "protocols", protocol_name)
    logger.info("Copying protocol modules. src={} dst={}".format(src, dest))
    try:
        shutil.copytree(src, dest)
    except Exception as e:
        logger.error(str(e))
        exit(-1)

    # make the 'protocols' folder a Python package.
    logger.debug("Creating {}".format(os.path.join(agent_name, "protocols", "__init__.py")))
    Path(os.path.join(ctx.cwd, "protocols", "__init__.py")).touch(exist_ok=True)

    # add the protocol to the configurations.
    logger.debug("Registering the protocol into {}".format(DEFAULT_AEA_CONFIG_FILE))
    ctx.agent_config.protocols.add(protocol_name)
    ctx.agent_loader.dump(ctx.agent_config, open(os.path.join(ctx.cwd, DEFAULT_AEA_CONFIG_FILE), "w"))
Ejemplo n.º 27
0
def connection(click_context, connection_name):
    """Add a connection to the configuration file."""
    ctx = cast(Context, click_context.obj)
    agent_name = ctx.agent_config.agent_name
    logger.debug("Adding connection {} to the agent {}...".format(connection_name, agent_name))

    # check if we already have a connection with the same name
    logger.debug("Connection already supported by the agent: {}".format(ctx.agent_config.connections))
    if connection_name in ctx.agent_config.connections:
        logger.error("A connection with name '{}' already exists. Aborting...".format(connection_name))
        exit(-1)

    # check that the provided path points to a proper connection directory -> look for connection.yaml file.
    # first check in aea dir
    registry_path = ctx.agent_config.registry_path
    connection_configuration_filepath = Path(os.path.join(registry_path, "connections", connection_name, DEFAULT_CONNECTION_CONFIG_FILE))
    if not connection_configuration_filepath.exists():
        # then check in registry
        registry_path = AEA_DIR
        connection_configuration_filepath = Path(os.path.join(registry_path, "connections", connection_name, DEFAULT_CONNECTION_CONFIG_FILE))
        if not connection_configuration_filepath.exists():
            logger.error("Cannot find connection: '{}'.".format(connection_name))
            exit(-1)

    # try to load the connection configuration file
    try:
        connection_configuration = ctx.connection_loader.load(open(str(connection_configuration_filepath)))
        logger.info("Connection supports the following protocols: {}".format(connection_configuration.supported_protocols))
    except ValidationError as e:
        logger.error("Connection configuration file not valid: {}".format(str(e)))
        exit(-1)

    # copy the connection package into the agent's supported connections.
    src = str(Path(os.path.join(registry_path, "connections", connection_name)).absolute())
    dest = os.path.join(ctx.cwd, "connections", connection_name)
    logger.info("Copying connection modules. src={} dst={}".format(src, dest))
    try:
        shutil.copytree(src, dest)
    except Exception as e:
        logger.error(str(e))
        exit(-1)

    # make the 'connections' folder a Python package.
    connections_init_module = os.path.join(ctx.cwd, "connections", "__init__.py")
    logger.debug("Creating {}".format(connections_init_module))
    Path(connections_init_module).touch(exist_ok=True)

    # add the connections to the configurations.
    logger.debug("Registering the connection into {}".format(DEFAULT_AEA_CONFIG_FILE))
    ctx.agent_config.connections.add(connection_name)
    ctx.agent_loader.dump(ctx.agent_config, open(os.path.join(ctx.cwd, DEFAULT_AEA_CONFIG_FILE), "w"))
Ejemplo n.º 28
0
def get(ctx: Context, json_path: List[str]):
    """Get a field."""
    config_loader = cast(ConfigLoader, ctx.config.get("configuration_loader"))
    configuration_file_path = cast(str,
                                   ctx.config.get("configuration_file_path"))

    configuration_object = yaml.safe_load(open(configuration_file_path))
    config_loader.validator.validate(instance=configuration_object)

    parent_object_path = json_path[:-1]
    attribute_name = json_path[-1]
    try:
        parent_object = _get_parent_object(configuration_object,
                                           parent_object_path)
    except ValueError as e:
        logger.error(str(e))
        sys.exit(1)

    if attribute_name not in parent_object:
        logger.error("Attribute '{}' not found.".format(attribute_name))
        sys.exit(1)
    if not isinstance(parent_object.get(attribute_name),
                      (str, int, bool, float)):
        logger.error(
            "Attribute '{}' is not of primitive type.".format(attribute_name))
        sys.exit(1)

    attribute_value = parent_object.get(attribute_name)
    print(attribute_value)
Ejemplo n.º 29
0
def _find_connection_locally(ctx, connection_name):
    # check that the provided path points to a proper connection directory -> look for connection.yaml file.
    # first check in aea dir
    registry_path = ctx.agent_config.registry_path
    connection_configuration_filepath = Path(os.path.join(registry_path, "connections", connection_name, DEFAULT_CONNECTION_CONFIG_FILE))
    if not connection_configuration_filepath.exists():
        # then check in registry
        registry_path = AEA_DIR
        connection_configuration_filepath = Path(os.path.join(registry_path, "connections", connection_name, DEFAULT_CONNECTION_CONFIG_FILE))
        if not connection_configuration_filepath.exists():
            logger.error("Cannot find connection: '{}'.".format(connection_name))
            sys.exit(1)

    # try to load the connection configuration file
    try:
        connection_configuration = ctx.connection_loader.load(open(str(connection_configuration_filepath)))
        logger.info("Connection '{}' supports the following protocols: {}".format(connection_name, connection_configuration.restricted_to_protocols))
    except ValidationError as e:
        logger.error("Connection configuration file not valid: {}".format(str(e)))
        sys.exit(1)

    # copy the connection package into the agent's supported connections.
    src = str(Path(os.path.join(registry_path, "connections", connection_name)).absolute())
    dest = os.path.join(ctx.cwd, "connections", connection_name)
    logger.debug("Copying connection modules. src={} dst={}".format(src, dest))
    try:
        shutil.copytree(src, dest)
    except Exception as e:
        logger.error(str(e))
        sys.exit(1)
Ejemplo n.º 30
0
def _find_skill_locally(ctx, skill_name, click_context):
    # check that the provided path points to a proper skill directory -> look for skill.yaml file.
    # first check in aea dir
    registry_path = ctx.agent_config.registry_path
    skill_configuration_filepath = Path(os.path.join(registry_path, "skills", skill_name, DEFAULT_SKILL_CONFIG_FILE))
    if not skill_configuration_filepath.exists():
        # then check in registry
        registry_path = AEA_DIR
        skill_configuration_filepath = Path(os.path.join(registry_path, "skills", skill_name, DEFAULT_SKILL_CONFIG_FILE))
        if not skill_configuration_filepath.exists():
            logger.error("Cannot find skill: '{}'.".format(skill_name))
            sys.exit(1)

    # try to load the skill configuration file
    try:
        skill_configuration = ctx.skill_loader.load(open(str(skill_configuration_filepath)))
    except ValidationError as e:
        logger.error("Skill configuration file not valid: {}".format(str(e)))
        sys.exit(1)

    # copy the skill package into the agent's supported skills.
    src = str(Path(os.path.join(registry_path, "skills", skill_name)).absolute())
    dest = os.path.join(ctx.cwd, "skills", skill_name)
    logger.debug("Copying skill modules. src={} dst={}".format(src, dest))
    try:
        shutil.copytree(src, dest)
    except Exception as e:
        logger.error(str(e))
        sys.exit(1)

    # check for not supported protocol, and add it.
    for protocol_name in skill_configuration.protocols:
        if protocol_name not in ctx.agent_config.protocols:
            logger.debug("Adding protocol '{}' to the agent...".format(protocol_name))
            click_context.invoke(protocol, protocol_name=protocol_name)