def fetch_package(obj_type: str, public_id: PublicId, cwd: str, dest: str) -> Path: """ Fetch a package (connection/contract/protocol/skill) from Registry. :param obj_type: str type of object you want to fetch: 'connection', 'protocol', 'skill' :param public_id: str public ID of object. :param cwd: str path to current working directory. :return: package path """ logger.debug("Fetching {obj_type} {public_id} from Registry...".format( public_id=public_id, obj_type=obj_type)) logger.debug("Downloading {obj_type} {public_id}...".format( public_id=public_id, obj_type=obj_type)) package_meta = get_package_meta(obj_type, public_id) file_url = package_meta["file"] filepath = download_file(file_url, cwd) # next code line is needed because the items are stored in tarball packages as folders dest = os.path.split(dest)[0] logger.debug("Extracting {obj_type} {public_id}...".format( public_id=public_id, obj_type=obj_type)) extract(filepath, dest) logger.debug("Successfully fetched {obj_type} '{public_id}'.".format( public_id=public_id, obj_type=obj_type)) package_path = os.path.join(dest, public_id.name) return Path(package_path)
def download_package(package_id: PackageId, destination_path: str) -> None: """Download a package into a directory.""" api_path = f"/{package_id.package_type.to_plural()}/{package_id.author}/{package_id.name}/{package_id.public_id.LATEST_VERSION}" resp = cast(JSONLike, request_api("GET", api_path)) file_url = cast(str, resp["file"]) filepath = download_file(file_url, destination_path) extract(filepath, destination_path)
def fetch_agent(ctx: Context, public_id: PublicId) -> None: """ Fetch Agent from Registry. :param public_id: str public ID of desirable Agent. :return: None """ author, name, version = public_id.author, public_id.name, public_id.version api_path = "/agents/{}/{}/{}".format(author, name, version) resp = request_api("GET", api_path) file_url = resp["file"] target_folder = os.path.join(ctx.cwd, name) os.makedirs(target_folder, exist_ok=True) click.echo("Fetching dependencies...") for item_type in ("connection", "skill", "protocol"): item_type_plural = item_type + "s" for item_public_id in resp[item_type_plural]: item_public_id = PublicId.from_str(item_public_id) try: fetch_package(item_type, item_public_id, target_folder) except Exception as e: rmtree(target_folder) raise click.ClickException( 'Unable to fetch dependency for agent "{}", aborting. {}'.format( name, e ) ) click.echo("Dependencies successfully fetched.") filepath = download_file(file_url, ctx.cwd) extract(filepath, target_folder) click.echo("Agent {} successfully fetched to {}.".format(name, target_folder))
def fetch_package(obj_type: str, public_id: PublicId, cwd: str, dest: str) -> Path: """ Fetch a package (connection/contract/protocol/skill) from Registry. :param obj_type: str type of object you want to fetch: 'connection', 'protocol', 'skill' :param public_id: str public ID of object. :param cwd: str path to current working directory. :return: package path """ logger.debug("Fetching {obj_type} {public_id} from Registry...".format( public_id=public_id, obj_type=obj_type)) author, name, version = public_id.author, public_id.name, public_id.version item_type_plural = obj_type + "s" # used for API and folder paths api_path = "/{}/{}/{}/{}".format(item_type_plural, author, name, version) resp = request_api("GET", api_path) file_url = resp["file"] logger.debug("Downloading {obj_type} {public_id}...".format( public_id=public_id, obj_type=obj_type)) filepath = download_file(file_url, cwd) # next code line is needed because the items are stored in tarball packages as folders dest = os.path.split(dest)[ 0] # TODO: replace this hotfix with a proper solution logger.debug("Extracting {obj_type} {public_id}...".format( public_id=public_id, obj_type=obj_type)) extract(filepath, dest) click.echo("Successfully fetched {obj_type}: {public_id}.".format( public_id=public_id, obj_type=obj_type)) package_path = os.path.join(dest, public_id.name) return Path(package_path)
def fetch_agent( click_context, public_id: PublicId, alias: Optional[str] = None ) -> None: """ Fetch Agent from Registry. :param ctx: Context :param public_id: str public ID of desirable Agent. :param click_context: the click context. :param alias: an optional alias. :return: None """ author, name, version = public_id.author, public_id.name, public_id.version api_path = "/agents/{}/{}/{}".format(author, name, version) resp = request_api("GET", api_path) file_url = resp["file"] ctx = cast(Context, click_context.obj) filepath = download_file(file_url, ctx.cwd) folder_name = name if alias is None else alias aea_folder = os.path.join(ctx.cwd, folder_name) ctx.clean_paths.append(aea_folder) extract(filepath, ctx.cwd) if alias is not None: os.rename(name, alias) ctx.cwd = aea_folder try_to_load_agent_config(ctx) if alias is not None: ctx.agent_config.agent_name = alias ctx.agent_loader.dump( ctx.agent_config, open(os.path.join(ctx.cwd, DEFAULT_AEA_CONFIG_FILE), "w") ) click.echo("Fetching dependencies...") for item_type in ("connection", "contract", "skill", "protocol"): item_type_plural = item_type + "s" # initialize fetched agent with empty folders for custom packages custom_items_folder = os.path.join(ctx.cwd, item_type_plural) os.makedirs(custom_items_folder) config = getattr(ctx.agent_config, item_type_plural) for item_public_id in config: try: _add_item(click_context, item_type, item_public_id) except Exception as e: raise click.ClickException( 'Unable to fetch dependency for agent "{}", aborting. {}'.format( name, e ) ) click.echo("Dependencies successfully fetched.") click.echo("Agent {} successfully fetched to {}.".format(name, aea_folder))
def test_extract_positive(self, tarfile_open_mock, os_remove_mock): """Test for extract method positive result.""" source = "file.tar.gz" target = "target-folder" tar_mock = mock.Mock() tar_mock.extractall = lambda path: None tar_mock.close = lambda: None tarfile_open_mock.return_value = tar_mock extract(source, target) tarfile_open_mock.assert_called_once_with(source, "r:gz") os_remove_mock.assert_called_once_with(source)
def fetch_agent(ctx: Context, public_id: PublicId, click_context) -> None: """ Fetch Agent from Registry. :param public_id: str public ID of desirable Agent. :return: None """ author, name, version = public_id.author, public_id.name, public_id.version api_path = "/agents/{}/{}/{}".format(author, name, version) resp = request_api("GET", api_path) file_url = resp["file"] filepath = download_file(file_url, ctx.cwd) extract(filepath, ctx.cwd) target_folder = os.path.join(ctx.cwd, name) ctx.cwd = target_folder try_to_load_agent_config(ctx) click.echo("Fetching dependencies...") for item_type in ("connection", "contract", "skill", "protocol"): item_type_plural = item_type + "s" # initialize fetched agent with empty folders for custom packages custom_items_folder = os.path.join(ctx.cwd, item_type_plural) os.makedirs(custom_items_folder) config = getattr(ctx.agent_config, item_type_plural) for item_public_id in config: try: _add_item(click_context, item_type, item_public_id) except Exception as e: rmtree(target_folder) raise click.ClickException( 'Unable to fetch dependency for agent "{}", aborting. {}'. format(name, e)) click.echo("Dependencies successfully fetched.") click.echo("Agent {} successfully fetched to {}.".format( name, target_folder))
def test_extract_wrong_file_type(self): """Test for extract method wrong file type.""" source = "file.wrong" target = "target-folder" with self.assertRaises(Exception): extract(source, target)
def fetch_agent( ctx: Context, public_id: PublicId, alias: Optional[str] = None, target_dir: Optional[str] = None, ) -> None: """ Fetch Agent from Registry. :param ctx: Context :param public_id: str public ID of desirable agent. :param alias: an optional alias. :param target_dir: the target directory to which the agent is fetched. :return: None """ author, name, version = public_id.author, public_id.name, public_id.version folder_name = target_dir or (name if alias is None else alias) aea_folder = os.path.join(ctx.cwd, folder_name) if os.path.exists(aea_folder): raise ClickException( f'Item "{folder_name}" already exists in target folder.') ctx.clean_paths.append(aea_folder) api_path = f"/agents/{author}/{name}/{version}" resp = request_api("GET", api_path) file_url = resp["file"] filepath = download_file(file_url, ctx.cwd) extract(filepath, ctx.cwd) if alias or target_dir: shutil.move( os.path.join(ctx.cwd, name), aea_folder, ) ctx.cwd = aea_folder try_to_load_agent_config(ctx) if alias is not None: ctx.agent_config.agent_name = alias with open(os.path.join(ctx.cwd, DEFAULT_AEA_CONFIG_FILE), "w") as fp: ctx.agent_loader.dump(ctx.agent_config, fp) click.echo("Fetching dependencies...") for item_type in (CONNECTION, CONTRACT, SKILL, PROTOCOL): item_type_plural = item_type + "s" # initialize fetched agent with empty folders for custom packages custom_items_folder = os.path.join(ctx.cwd, item_type_plural) os.makedirs(custom_items_folder) config = getattr(ctx.agent_config, item_type_plural) for item_public_id in config: try: add_item(ctx, item_type, item_public_id) except Exception as e: raise click.ClickException( f'Unable to fetch dependency for agent "{name}", aborting. {e}' ) click.echo("Dependencies successfully fetched.") click.echo(f"Agent {name} successfully fetched to {aea_folder}.")