From b2bf23dcfec5f287157e651e300b4bc8a3cf492c Mon Sep 17 00:00:00 2001 From: BraisedPork <46232992+braisedpork1964@users.noreply.github.com> Date: Mon, 18 Nov 2024 12:04:33 +0800 Subject: [PATCH] [Fix] Alternative for `aioify` (#274) replace `aioify` with `asyncify` --- .pre-commit-config.yaml | 2 - lagent/actions/arxiv_search.py | 12 +- lagent/actions/google_scholar_search.py | 185 +++++++++++++----------- lagent/actions/ppt.py | 43 +++--- lagent/actions/python_interpreter.py | 8 +- requirements/runtime.txt | 5 +- 6 files changed, 132 insertions(+), 123 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 1bdaecce..5066bc49 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -13,8 +13,6 @@ repos: hooks: - id: black args: ["--line-length", "119", "--skip-string-normalization"] - - - repo: https://github.com/pre-commit/pre-commit-hooks rev: v4.5.0 hooks: diff --git a/lagent/actions/arxiv_search.py b/lagent/actions/arxiv_search.py index af57db58..43ba7c05 100644 --- a/lagent/actions/arxiv_search.py +++ b/lagent/actions/arxiv_search.py @@ -1,6 +1,6 @@ from typing import Optional, Type -from aioify import aioify +from asyncer import asyncify from lagent.actions.base_action import AsyncActionMixin, BaseAction, tool_api from lagent.actions.parser import BaseParser, JsonParser @@ -42,12 +42,10 @@ def get_arxiv_article_information(self, query: str) -> dict: try: results = arxiv.Search( # type: ignore - query[:self.max_query_len], - max_results=self.top_k_results).results() + query[: self.max_query_len], max_results=self.top_k_results + ).results() except Exception as exc: - return ActionReturn( - errmsg=f'Arxiv exception: {exc}', - state=ActionStatusCode.HTTP_ERROR) + return ActionReturn(errmsg=f'Arxiv exception: {exc}', state=ActionStatusCode.HTTP_ERROR) docs = [ f'Published: {result.updated.date()}\nTitle: {result.title}\n' f'Authors: {", ".join(a.name for a in result.authors)}\n' @@ -67,7 +65,7 @@ class AsyncArxivSearch(AsyncActionMixin, ArxivSearch): """ @tool_api(explode_return=True) - @aioify + @asyncify def get_arxiv_article_information(self, query: str) -> dict: """Run Arxiv search and get the article meta information. diff --git a/lagent/actions/google_scholar_search.py b/lagent/actions/google_scholar_search.py index 21822d6a..6247f147 100644 --- a/lagent/actions/google_scholar_search.py +++ b/lagent/actions/google_scholar_search.py @@ -2,7 +2,7 @@ import os from typing import Optional, Type -from aioify import aioify +from asyncer import asyncify from lagent.actions.base_action import AsyncActionMixin, BaseAction, tool_api from lagent.schema import ActionReturn, ActionStatusCode @@ -31,7 +31,8 @@ def __init__( if api_key is None: raise ValueError( 'Please set Serper API key either in the environment ' - 'as SERPER_API_KEY or pass it as `api_key` parameter.') + 'as SERPER_API_KEY or pass it as `api_key` parameter.' + ) self.api_key = api_key @tool_api(explode_return=True) @@ -78,6 +79,7 @@ def search_google_scholar( - pub_info: publication information of selected papers """ from serpapi import GoogleSearch + params = { 'q': query, 'engine': 'google_scholar', @@ -94,7 +96,7 @@ def search_google_scholar( 'as_sdt': as_sdt, 'safe': safe, 'filter': filter, - 'as_vis': as_vis + 'as_vis': as_vis, } search = GoogleSearch(params) try: @@ -112,27 +114,24 @@ def search_google_scholar( cited_by.append(citation['total']) snippets.append(item['snippet']) organic_id.append(item['result_id']) - return dict( - title=title, - cited_by=cited_by, - organic_id=organic_id, - snippets=snippets) + return dict(title=title, cited_by=cited_by, organic_id=organic_id, snippets=snippets) except Exception as e: - return ActionReturn( - errmsg=str(e), state=ActionStatusCode.HTTP_ERROR) + return ActionReturn(errmsg=str(e), state=ActionStatusCode.HTTP_ERROR) @tool_api(explode_return=True) - def get_author_information(self, - author_id: str, - hl: Optional[str] = None, - view_op: Optional[str] = None, - sort: Optional[str] = None, - citation_id: Optional[str] = None, - start: Optional[int] = None, - num: Optional[int] = None, - no_cache: Optional[bool] = None, - async_req: Optional[bool] = None, - output: Optional[str] = None) -> dict: + def get_author_information( + self, + author_id: str, + hl: Optional[str] = None, + view_op: Optional[str] = None, + sort: Optional[str] = None, + citation_id: Optional[str] = None, + start: Optional[int] = None, + num: Optional[int] = None, + no_cache: Optional[bool] = None, + async_req: Optional[bool] = None, + output: Optional[str] = None, + ) -> dict: """Search for an author's information by author's id provided by get_author_id. Args: @@ -155,6 +154,7 @@ def get_author_information(self, * website: the author's homepage url """ from serpapi import GoogleSearch + params = { 'engine': 'google_scholar_author', 'author_id': author_id, @@ -167,7 +167,7 @@ def get_author_information(self, 'num': num, 'no_cache': no_cache, 'async': async_req, - 'output': output + 'output': output, } try: search = GoogleSearch(params) @@ -178,20 +178,19 @@ def get_author_information(self, name=author['name'], affiliations=author.get('affiliations', ''), website=author.get('website', ''), - articles=[ - dict(title=article['title'], authors=article['authors']) - for article in articles[:3] - ]) + articles=[dict(title=article['title'], authors=article['authors']) for article in articles[:3]], + ) except Exception as e: - return ActionReturn( - errmsg=str(e), state=ActionStatusCode.HTTP_ERROR) + return ActionReturn(errmsg=str(e), state=ActionStatusCode.HTTP_ERROR) @tool_api(explode_return=True) - def get_citation_format(self, - q: str, - no_cache: Optional[bool] = None, - async_: Optional[bool] = None, - output: Optional[str] = 'json') -> dict: + def get_citation_format( + self, + q: str, + no_cache: Optional[bool] = None, + async_: Optional[bool] = None, + output: Optional[str] = 'json', + ) -> dict: """Function to get MLA citation format by an identification of organic_result's id provided by search_google_scholar. Args: @@ -206,13 +205,14 @@ def get_citation_format(self, * citation: the citation format of the article """ from serpapi import GoogleSearch + params = { 'q': q, 'engine': 'google_scholar_cite', 'api_key': self.api_key, 'no_cache': no_cache, 'async': async_, - 'output': output + 'output': output, } try: search = GoogleSearch(params) @@ -221,18 +221,19 @@ def get_citation_format(self, citation_info = citation[0]['snippet'] return citation_info except Exception as e: - return ActionReturn( - errmsg=str(e), state=ActionStatusCode.HTTP_ERROR) + return ActionReturn(errmsg=str(e), state=ActionStatusCode.HTTP_ERROR) @tool_api(explode_return=True) - def get_author_id(self, - mauthors: str, - hl: Optional[str] = 'en', - after_author: Optional[str] = None, - before_author: Optional[str] = None, - no_cache: Optional[bool] = False, - _async: Optional[bool] = False, - output: Optional[str] = 'json') -> dict: + def get_author_id( + self, + mauthors: str, + hl: Optional[str] = 'en', + after_author: Optional[str] = None, + before_author: Optional[str] = None, + no_cache: Optional[bool] = False, + _async: Optional[bool] = False, + output: Optional[str] = 'json', + ) -> dict: """The getAuthorId function is used to get the author's id by his or her name. Args: @@ -249,6 +250,7 @@ def get_author_id(self, * author_id: the author_id of the author """ from serpapi import GoogleSearch + params = { 'mauthors': mauthors, 'engine': 'google_scholar_profiles', @@ -258,7 +260,7 @@ def get_author_id(self, 'before_author': before_author, 'no_cache': no_cache, 'async': _async, - 'output': output + 'output': output, } try: search = GoogleSearch(params) @@ -267,8 +269,7 @@ def get_author_id(self, author_info = dict(author_id=profile[0]['author_id']) return author_info except Exception as e: - return ActionReturn( - errmsg=str(e), state=ActionStatusCode.HTTP_ERROR) + return ActionReturn(errmsg=str(e), state=ActionStatusCode.HTTP_ERROR) class AsyncGoogleScholar(AsyncActionMixin, GoogleScholar): @@ -283,7 +284,7 @@ class AsyncGoogleScholar(AsyncActionMixin, GoogleScholar): """ @tool_api(explode_return=True) - @aioify + @asyncify def search_google_scholar( self, query: str, @@ -326,23 +327,38 @@ def search_google_scholar( - organic_id: a list of the organic results' ids of the three selected papers - pub_info: publication information of selected papers """ - return super().search_google_scholar(query, cites, as_ylo, as_yhi, - scisbd, cluster, hl, lr, start, - num, as_sdt, safe, filter, as_vis) + return super().search_google_scholar( + query, + cites, + as_ylo, + as_yhi, + scisbd, + cluster, + hl, + lr, + start, + num, + as_sdt, + safe, + filter, + as_vis, + ) @tool_api(explode_return=True) - @aioify - def get_author_information(self, - author_id: str, - hl: Optional[str] = None, - view_op: Optional[str] = None, - sort: Optional[str] = None, - citation_id: Optional[str] = None, - start: Optional[int] = None, - num: Optional[int] = None, - no_cache: Optional[bool] = None, - async_req: Optional[bool] = None, - output: Optional[str] = None) -> dict: + @asyncify + def get_author_information( + self, + author_id: str, + hl: Optional[str] = None, + view_op: Optional[str] = None, + sort: Optional[str] = None, + citation_id: Optional[str] = None, + start: Optional[int] = None, + num: Optional[int] = None, + no_cache: Optional[bool] = None, + async_req: Optional[bool] = None, + output: Optional[str] = None, + ) -> dict: """Search for an author's information by author's id provided by get_author_id. Args: @@ -364,17 +380,19 @@ def get_author_information(self, * articles: at most 3 articles by the author * website: the author's homepage url """ - return super().get_author_information(author_id, hl, view_op, sort, - citation_id, start, num, - no_cache, async_req, output) + return super().get_author_information( + author_id, hl, view_op, sort, citation_id, start, num, no_cache, async_req, output + ) @tool_api(explode_return=True) - @aioify - def get_citation_format(self, - q: str, - no_cache: Optional[bool] = None, - async_: Optional[bool] = None, - output: Optional[str] = 'json') -> dict: + @asyncify + def get_citation_format( + self, + q: str, + no_cache: Optional[bool] = None, + async_: Optional[bool] = None, + output: Optional[str] = 'json', + ) -> dict: """Function to get MLA citation format by an identification of organic_result's id provided by search_google_scholar. Args: @@ -391,15 +409,17 @@ def get_citation_format(self, return super().get_citation_format(q, no_cache, async_, output) @tool_api(explode_return=True) - @aioify - def get_author_id(self, - mauthors: str, - hl: Optional[str] = 'en', - after_author: Optional[str] = None, - before_author: Optional[str] = None, - no_cache: Optional[bool] = False, - _async: Optional[bool] = False, - output: Optional[str] = 'json') -> dict: + @asyncify + def get_author_id( + self, + mauthors: str, + hl: Optional[str] = 'en', + after_author: Optional[str] = None, + before_author: Optional[str] = None, + no_cache: Optional[bool] = False, + _async: Optional[bool] = False, + output: Optional[str] = 'json', + ) -> dict: """The getAuthorId function is used to get the author's id by his or her name. Args: @@ -415,5 +435,4 @@ def get_author_id(self, :class:`dict`: author id * author_id: the author_id of the author """ - return super().get_author_id(mauthors, hl, after_author, before_author, - no_cache, _async, output) + return super().get_author_id(mauthors, hl, after_author, before_author, no_cache, _async, output) diff --git a/lagent/actions/ppt.py b/lagent/actions/ppt.py index 7d297e9a..38bcfa84 100644 --- a/lagent/actions/ppt.py +++ b/lagent/actions/ppt.py @@ -1,6 +1,6 @@ from typing import Dict, Optional, Type -from aioify import aioify +from asyncer import asyncify from lagent.actions.base_action import AsyncActionMixin, BaseAction, tool_api from lagent.actions.parser import BaseParser, JsonParser @@ -42,6 +42,7 @@ def create_file(self, theme: str, abs_location: str) -> dict: * status: the result of the execution """ from pptx import Presentation + self.location = abs_location try: self.pointer = Presentation(self.theme_mapping[theme]['template']) @@ -63,10 +64,8 @@ def add_first_page(self, title: str, subtitle: str) -> dict: :class:`dict`: operation status * status: the result of the execution """ - layout_name = self.theme_mapping[ - self.pointer.slide_master.name]['title'] - layout = next(i for i in self.pointer.slide_master.slide_layouts - if i.name == layout_name) + layout_name = self.theme_mapping[self.pointer.slide_master.name]['title'] + layout = next(i for i in self.pointer.slide_master.slide_layouts if i.name == layout_name) slide = self.pointer.slides.add_slide(layout) ph_title, ph_subtitle = slide.placeholders ph_title.text = title @@ -85,11 +84,9 @@ def add_text_page(self, title: str, bullet_items: str) -> dict: Returns: :class:`dict`: operation status * status: the result of the execution - """ - layout_name = self.theme_mapping[ - self.pointer.slide_master.name]['single'] - layout = next(i for i in self.pointer.slide_master.slide_layouts - if i.name == layout_name) + """ # noqa: E501 + layout_name = self.theme_mapping[self.pointer.slide_master.name]['single'] + layout = next(i for i in self.pointer.slide_master.slide_layouts if i.name == layout_name) slide = self.pointer.slides.add_slide(layout) ph_title, ph_body = slide.placeholders ph_title.text = title @@ -105,8 +102,7 @@ def add_text_page(self, title: str, bullet_items: str) -> dict: return dict(status='added page') @tool_api(explode_return=True) - def add_text_image_page(self, title: str, bullet_items: str, - image: str) -> dict: + def add_text_image_page(self, title: str, bullet_items: str, image: str) -> dict: """Add a text page with one image. Image should be a path. Args: @@ -117,11 +113,11 @@ def add_text_image_page(self, title: str, bullet_items: str, Returns: :class:`dict`: operation status * status: the result of the execution - """ + """ # noqa: E501 from PIL import Image + layout_name = self.theme_mapping[self.pointer.slide_master.name]['two'] - layout = next(i for i in self.pointer.slide_master.slide_layouts - if i.name == layout_name) + layout = next(i for i in self.pointer.slide_master.slide_layouts if i.name == layout_name) slide = self.pointer.slides.add_slide(layout) ph_title, ph_body1, ph_body2 = slide.placeholders ph_title.text = title @@ -165,7 +161,7 @@ class AsyncPPT(AsyncActionMixin, PPT): """Plugin to create ppt slides with text, paragraph, images in good looking styles.""" @tool_api(explode_return=True) - @aioify + @asyncify def create_file(self, theme: str, abs_location: str) -> dict: """Create a pptx file with specific themes. @@ -180,7 +176,7 @@ def create_file(self, theme: str, abs_location: str) -> dict: return super().create_file(theme, abs_location) @tool_api(explode_return=True) - @aioify + @asyncify def add_first_page(self, title: str, subtitle: str) -> dict: """Add the first page of ppt. @@ -195,7 +191,7 @@ def add_first_page(self, title: str, subtitle: str) -> dict: return super().add_first_page(title, subtitle) @tool_api(explode_return=True) - @aioify + @asyncify def add_text_page(self, title: str, bullet_items: str) -> dict: """Add text page of ppt. @@ -206,13 +202,12 @@ def add_text_page(self, title: str, bullet_items: str) -> dict: Returns: :class:`dict`: operation status * status: the result of the execution - """ + """ # noqa: E501 return super().add_text_page(title, bullet_items) @tool_api(explode_return=True) - @aioify - def add_text_image_page(self, title: str, bullet_items: str, - image: str) -> dict: + @asyncify + def add_text_image_page(self, title: str, bullet_items: str, image: str) -> dict: """Add a text page with one image. Image should be a path. Args: @@ -223,11 +218,11 @@ def add_text_image_page(self, title: str, bullet_items: str, Returns: :class:`dict`: operation status * status: the result of the execution - """ + """ # noqa: E501 return super().add_text_image_page(title, bullet_items, image) @tool_api(explode_return=True) - @aioify + @asyncify def submit_file(self) -> dict: """When all steps done, YOU MUST use submit_file() to submit your work. diff --git a/lagent/actions/python_interpreter.py b/lagent/actions/python_interpreter.py index c7dbc282..8bd3266b 100644 --- a/lagent/actions/python_interpreter.py +++ b/lagent/actions/python_interpreter.py @@ -4,7 +4,7 @@ from contextlib import redirect_stdout from typing import Any, Optional, Type -from aioify import aioify +from asyncer import asyncify from lagent.actions.base_action import AsyncActionMixin, BaseAction, tool_api from lagent.actions.parser import BaseParser, JsonParser @@ -18,8 +18,7 @@ class GenericRuntime: def __init__(self): self._global_vars = copy.copy(self.GLOBAL_DICT) - self._local_vars = copy.copy( - self.LOCAL_DICT) if self.LOCAL_DICT else None + self._local_vars = copy.copy(self.LOCAL_DICT) if self.LOCAL_DICT else None for c in self.HEADERS: self.exec_code(c) @@ -85,6 +84,7 @@ def solution(): command (:class:`str`): Python code snippet """ from func_timeout import FunctionTimedOut, func_set_timeout + self.runtime = GenericRuntime() try: tool_return = func_set_timeout(self.timeout)(self._call)(command) @@ -151,7 +151,7 @@ class AsyncPythonInterpreter(AsyncActionMixin, PythonInterpreter): """ @tool_api - @aioify + @asyncify def run(self, command: str) -> ActionReturn: """用来执行Python代码。代码必须是一个函数,函数名必须得是 'solution',代码对应你的思考过程。代码实例格式如下: diff --git a/requirements/runtime.txt b/requirements/runtime.txt index 9d9e4dff..6fcd4ea1 100644 --- a/requirements/runtime.txt +++ b/requirements/runtime.txt @@ -1,7 +1,7 @@ -aioify aiohttp arxiv asyncache +asyncer distro duckduckgo_search==5.3.1b1 filelock @@ -10,11 +10,10 @@ griffe<1.0 json5 jsonschema jupyter==1.0.0 -jupyter_core==5.7.2 jupyter_client==8.6.2 +jupyter_core==5.7.2 pydantic==2.6.4 requests -stdlib_list==0.10.0 termcolor tiktoken timeout-decorator