diff --git a/src/backend/base/langflow/__main__.py b/src/backend/base/langflow/__main__.py index 1a6a01b3a..b9bda3211 100644 --- a/src/backend/base/langflow/__main__.py +++ b/src/backend/base/langflow/__main__.py @@ -461,7 +461,7 @@ def migration( if not typer.confirm( "This will delete all data necessary to fix migrations. Are you sure you want to continue?" ): - raise typer.Abort() + raise typer.Abort initialize_services(fix_migration=fix) db_service = get_db_service() diff --git a/src/backend/base/langflow/base/agents/agent.py b/src/backend/base/langflow/base/agents/agent.py index 0402f96b5..554e72413 100644 --- a/src/backend/base/langflow/base/agents/agent.py +++ b/src/backend/base/langflow/base/agents/agent.py @@ -50,7 +50,6 @@ class LCAgentComponent(Component): @abstractmethod def build_agent(self) -> AgentExecutor: """Create the agent.""" - pass async def message_response(self) -> Message: """Run the agent and return the response.""" @@ -156,4 +155,3 @@ class LCToolsAgentComponent(LCAgentComponent): @abstractmethod def create_agent_runnable(self) -> Runnable: """Create the agent.""" - pass diff --git a/src/backend/base/langflow/base/data/utils.py b/src/backend/base/langflow/base/data/utils.py index 612bee050..7553d047c 100644 --- a/src/backend/base/langflow/base/data/utils.py +++ b/src/backend/base/langflow/base/data/utils.py @@ -140,7 +140,7 @@ def parse_text_file_to_data(file_path: str, silent_errors: bool) -> Data | None: text = [normalize_text(item) if isinstance(item, str) else item for item in text] text = orjson.dumps(text).decode("utf-8") - elif file_path.endswith(".yaml") or file_path.endswith(".yml"): + elif file_path.endswith((".yaml", ".yml")): text = yaml.safe_load(text) elif file_path.endswith(".xml"): xml_element = ET.fromstring(text) diff --git a/src/backend/base/langflow/base/document_transformers/model.py b/src/backend/base/langflow/base/document_transformers/model.py index d698f7e91..41f659067 100644 --- a/src/backend/base/langflow/base/document_transformers/model.py +++ b/src/backend/base/langflow/base/document_transformers/model.py @@ -39,11 +39,9 @@ class LCDocumentTransformerComponent(Component): """ Get the data input. """ - pass @abstractmethod def build_document_transformer(self) -> BaseDocumentTransformer: """ Build the text splitter. """ - pass diff --git a/src/backend/base/langflow/base/langchain_utilities/model.py b/src/backend/base/langflow/base/langchain_utilities/model.py index 49772b270..7e41a6a0e 100644 --- a/src/backend/base/langflow/base/langchain_utilities/model.py +++ b/src/backend/base/langflow/base/langchain_utilities/model.py @@ -28,11 +28,9 @@ class LCToolComponent(Component): """ Run model and return the output. """ - pass @abstractmethod def build_tool(self) -> Tool | Sequence[Tool]: """ Build the tool. """ - pass diff --git a/src/backend/base/langflow/base/textsplitters/model.py b/src/backend/base/langflow/base/textsplitters/model.py index 413d73d6f..058e21f42 100644 --- a/src/backend/base/langflow/base/textsplitters/model.py +++ b/src/backend/base/langflow/base/textsplitters/model.py @@ -26,4 +26,3 @@ class LCTextSplitterComponent(LCDocumentTransformerComponent): """ Build the text splitter. """ - pass diff --git a/src/backend/base/langflow/components/chains/RetrievalQA.py b/src/backend/base/langflow/components/chains/RetrievalQA.py index c6ef848ec..9c656ecb3 100644 --- a/src/backend/base/langflow/components/chains/RetrievalQA.py +++ b/src/backend/base/langflow/components/chains/RetrievalQA.py @@ -58,7 +58,7 @@ class RetrievalQAComponent(LCChainComponent): result_str = str(result.get("result", "")) if self.return_source_documents and len(source_docs): references_str = self.create_references_from_data(source_docs) - result_str = "\n".join([result_str, references_str]) + result_str = f"{result_str}\n{references_str}" # put the entire result to debug history, query and content self.status = {**result, "source_documents": source_docs, "output": result_str} return result_str diff --git a/src/backend/base/langflow/custom/code_parser/code_parser.py b/src/backend/base/langflow/custom/code_parser/code_parser.py index 9ceea82a3..66f29d6b7 100644 --- a/src/backend/base/langflow/custom/code_parser/code_parser.py +++ b/src/backend/base/langflow/custom/code_parser/code_parser.py @@ -343,7 +343,6 @@ class CodeParser: nodes.append(class_node) except Exception as exc: logger.error(f"Error finding base class node: {exc}") - pass nodes.insert(0, node) class_details = ClassCodeDetails( name=node.name, diff --git a/src/backend/base/langflow/custom/utils.py b/src/backend/base/langflow/custom/utils.py index 10ee795c2..31f825a83 100644 --- a/src/backend/base/langflow/custom/utils.py +++ b/src/backend/base/langflow/custom/utils.py @@ -128,7 +128,7 @@ def get_field_properties(extra_field): def process_type(field_type: str): - if field_type.startswith("list") or field_type.startswith("List"): + if field_type.startswith(("list", "List")): return extract_inner_type(field_type) # field_type is a string can be Prompt or Code too diff --git a/src/backend/base/langflow/initial_setup/starter_projects/hierarchical_tasks_agent.py b/src/backend/base/langflow/initial_setup/starter_projects/hierarchical_tasks_agent.py index 0581fff27..c461c70a7 100644 --- a/src/backend/base/langflow/initial_setup/starter_projects/hierarchical_tasks_agent.py +++ b/src/backend/base/langflow/initial_setup/starter_projects/hierarchical_tasks_agent.py @@ -37,7 +37,7 @@ def hierarchical_tasks_agent_graph(): template="""User's query: {query} -Respond to the user with as much as information as you can about the topic. Delete if needed. +Respond to the user with as much as information as you can about the topic. Delete if needed. If it is just a general query (e.g a greeting) you can respond them directly.""", query=chat_input.message_response, ) diff --git a/src/backend/base/langflow/inputs/input_mixin.py b/src/backend/base/langflow/inputs/input_mixin.py index 054a3de5a..0e095d40f 100644 --- a/src/backend/base/langflow/inputs/input_mixin.py +++ b/src/backend/base/langflow/inputs/input_mixin.py @@ -18,7 +18,7 @@ from langflow.schema.table import Column, TableSchema class FieldTypes(str, Enum): TEXT = "str" INTEGER = "int" - PASSWORD = "str" + PASSWORD = "str" # noqa: PIE796 FLOAT = "float" BOOLEAN = "bool" DICT = "dict" diff --git a/src/backend/base/langflow/services/storage/local.py b/src/backend/base/langflow/services/storage/local.py index 1c3a67daf..1044a76fe 100644 --- a/src/backend/base/langflow/services/storage/local.py +++ b/src/backend/base/langflow/services/storage/local.py @@ -1,3 +1,4 @@ +import asyncio from pathlib import Path from loguru import logger @@ -33,9 +34,12 @@ class LocalStorageService(StorageService): folder_path.mkdir(parents=True, exist_ok=True) file_path = folder_path / file_name - try: + def write_file(file_path: Path, data: bytes) -> None: with open(file_path, "wb") as f: f.write(data) + + try: + await asyncio.get_event_loop().run_in_executor(None, write_file, file_path, data) logger.info(f"File {file_name} saved successfully in flow {flow_id}.") except Exception as e: logger.error(f"Error saving file {file_name} in flow {flow_id}: {e}") @@ -55,9 +59,13 @@ class LocalStorageService(StorageService): logger.warning(f"File {file_name} not found in flow {flow_id}.") raise FileNotFoundError(f"File {file_name} not found in flow {flow_id}") - with open(file_path, "rb") as f: - logger.debug(f"File {file_name} retrieved successfully from flow {flow_id}.") - return f.read() + def read_file(file_path: Path) -> bytes: + with open(file_path, "rb") as f: + return f.read() + + content = await asyncio.get_event_loop().run_in_executor(None, read_file, file_path) + logger.debug(f"File {file_name} retrieved successfully from flow {flow_id}.") + return content async def list_files(self, flow_id: str): """ @@ -92,4 +100,4 @@ class LocalStorageService(StorageService): async def teardown(self): """Perform any cleanup operations when the service is being torn down.""" - pass # No specific teardown actions required for local + # No specific teardown actions required for local diff --git a/src/backend/base/langflow/services/storage/s3.py b/src/backend/base/langflow/services/storage/s3.py index 4426f377c..7292b7a0b 100644 --- a/src/backend/base/langflow/services/storage/s3.py +++ b/src/backend/base/langflow/services/storage/s3.py @@ -86,4 +86,3 @@ class S3StorageService(StorageService): async def teardown(self): """Perform any cleanup operations when the service is being torn down.""" # No specific teardown actions required for S3 storage at the moment. - pass diff --git a/src/backend/base/langflow/services/store/service.py b/src/backend/base/langflow/services/store/service.py index e827b28a9..0d9a32836 100644 --- a/src/backend/base/langflow/services/store/service.py +++ b/src/backend/base/langflow/services/store/service.py @@ -330,7 +330,7 @@ class StoreService(Service): async def download(self, api_key: str, component_id: UUID) -> DownloadComponentResponse: url = f"{self.components_url}/{component_id}" - params = {"fields": ",".join(["id", "name", "description", "data", "is_component", "metadata"])} + params = {"fields": "id,name,description,data,is_component,metadata"} if not self.download_webhook_url: raise ValueError("DOWNLOAD_WEBHOOK_URL is not set") component, _ = await self._get(url, api_key, params) @@ -420,14 +420,14 @@ class StoreService(Service): async def get_tags(self) -> list[dict[str, Any]]: url = f"{self.base_url}/items/tags" - params = {"fields": ",".join(["id", "name"])} + params = {"fields": "id,name"} tags, _ = await self._get(url, api_key=None, params=params) return tags async def get_user_likes(self, api_key: str) -> list[dict[str, Any]]: url = f"{self.base_url}/users/me" params = { - "fields": ",".join(["id", "likes"]), + "fields": "id,likes", } likes, _ = await self._get(url, api_key, params) return likes @@ -436,7 +436,7 @@ class StoreService(Service): url = f"{self.components_url}/{component_id}" params = { - "fields": ",".join(["id", "count(liked_by)"]), + "fields": "id,count(liked_by)", } result, _ = await self._get(url, api_key=api_key, params=params) if len(result) == 0: diff --git a/src/backend/base/pyproject.toml b/src/backend/base/pyproject.toml index 2f4f7202c..3c062695c 100644 --- a/src/backend/base/pyproject.toml +++ b/src/backend/base/pyproject.toml @@ -148,7 +148,34 @@ exclude = ["langflow/alembic"] line-length = 120 [tool.ruff.lint] -select = ["C4", "E", "F", "I", "UP"] +select = [ + "ASYNC", + "C4", + "COM", + "DJ", + "E", + "F", + "FLY", + "FURB", + "I", + "ICN", + "INT", + "LOG", + "NPY", + "PD", + "PIE", + "Q", + "RSE", + "SLOT", + "T10", + "TID", + "UP", + "W", + "YTT" +] +ignore = [ + "COM812", # Messes with the formatter +] [build-system] requires = ["hatchling"]