ref: Add ruff rules for pylint (PL) (#4032)

* Add ruff rules for pylint (PL)

* Changes following review
This commit is contained in:
Christophe Bornet 2024-10-08 17:56:49 +02:00 • committed by GitHub
commit f01ea48d61
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
45 changed files with 174 additions and 166 deletions

View file

@ -228,7 +228,7 @@ def wait_for_server_ready(host, port):
Wait for the server to become ready by polling the health endpoint.
"""
status_code = 0
while status_code != 200:
while status_code != httpx.codes.OK:
try:
status_code = httpx.get(f"http://{host}:{port}/health").status_code
except Exception:
@ -250,7 +250,6 @@ def run_on_windows(host, port, log_level, options, app):
"""
print_banner(host, port)
run_langflow(host, port, log_level, options, app)
return
def is_port_in_use(port, host="localhost"):

View file

@ -11,8 +11,11 @@ from langflow.logging.logger import log_buffer
log_router = APIRouter(tags=["Log"])
NUMBER_OF_NOT_SENT_BEFORE_KEEPALIVE = 5
async def event_generator(request: Request):
global log_buffer
global log_buffer # noqa: PLW0602
last_read_item = None
current_not_sent = 0
while not await request.is_disconnected():
@ -41,7 +44,7 @@ async def event_generator(request: Request):
yield f"{json.dumps({ts:msg})}\n\n"
else:
current_not_sent += 1
if current_not_sent == 5:
if current_not_sent == NUMBER_OF_NOT_SENT_BEFORE_KEEPALIVE:
current_not_sent = 0
yield "keepalive\n\n"
@ -57,7 +60,7 @@ async def stream_logs(
it establishes a long-lived connection to the server and receives log messages in real-time
the client should use the head "Accept: text/event-stream"
"""
global log_buffer
global log_buffer # noqa: PLW0602
if log_buffer.enabled() is False:
raise HTTPException(
status_code=HTTPStatus.NOT_IMPLEMENTED,
@ -73,7 +76,7 @@ async def logs(
lines_after: int = Query(0, description="The number of logs after the timestamp"),
timestamp: int = Query(0, description="The timestamp to start getting logs from"),
):
global log_buffer
global log_buffer # noqa: PLW0602
if log_buffer.enabled() is False:
raise HTTPException(
status_code=HTTPStatus.NOT_IMPLEMENTED,
@ -91,11 +94,10 @@ async def logs(
detail="Timestamp is required when requesting logs after the timestamp",
)
content = log_buffer.get_last_n(10) if lines_before <= 0 else log_buffer.get_last_n(lines_before)
elif lines_before > 0:
content = log_buffer.get_before_timestamp(timestamp=timestamp, lines=lines_before)
elif lines_after > 0:
content = log_buffer.get_after_timestamp(timestamp=timestamp, lines=lines_after)
else:
if lines_before > 0:
content = log_buffer.get_before_timestamp(timestamp=timestamp, lines=lines_before)
elif lines_after > 0:
content = log_buffer.get_after_timestamp(timestamp=timestamp, lines=lines_after)
else:
content = log_buffer.get_before_timestamp(timestamp=timestamp, lines=10)
content = log_buffer.get_before_timestamp(timestamp=timestamp, lines=10)
return JSONResponse(content=content)

View file

@ -1,6 +1,7 @@
from __future__ import annotations
import uuid
from datetime import timedelta
from typing import TYPE_CHECKING, Any
from fastapi import HTTPException
@ -114,15 +115,18 @@ def format_elapsed_time(elapsed_time: float) -> str:
- Less than 1 minute: returns seconds rounded to 2 decimals
- 1 minute or more: returns minutes and seconds
"""
if elapsed_time < 1:
milliseconds = int(round(elapsed_time * 1000))
delta = timedelta(seconds=elapsed_time)
if delta < timedelta(seconds=1):
milliseconds = round(delta / timedelta(milliseconds=1))
return f"{milliseconds} ms"
if elapsed_time < 60:
if delta < timedelta(minutes=1):
seconds = round(elapsed_time, 2)
unit = "second" if seconds == 1 else "seconds"
return f"{seconds} {unit}"
minutes = int(elapsed_time // 60)
seconds = round(elapsed_time % 60, 2)
minutes = delta // timedelta(minutes=1)
seconds = round((delta - timedelta(minutes=minutes)).total_seconds(), 2)
minutes_unit = "minute" if minutes == 1 else "minutes"
seconds_unit = "second" if seconds == 1 else "seconds"
return f"{minutes} {minutes_unit}, {seconds} {seconds_unit}"

View file

@ -137,7 +137,7 @@ def update_folder(
folder_data = existing_folder.model_dump(exclude_unset=True)
for key, value in folder_data.items():
if key != "components" and key != "flows":
if key not in ("components", "flows"):
setattr(existing_folder, key, value)
session.add(existing_folder)
session.commit()

View file

@ -12,6 +12,8 @@ from langflow.field_typing import Tool
from langflow.inputs import MultilineInput, SecretStrInput, StrInput
from langflow.schema import Data
MIN_ROWS_IN_TABLE = 3
class AddContentToPage(LCToolComponent):
display_name: str = "Add Content to Page "
@ -91,12 +93,8 @@ class AddContentToPage(LCToolComponent):
if text.startswith("#"):
heading_level = text.count("#", 0, 6)
heading_text = text[heading_level:].strip()
if heading_level == 1:
blocks.append(self.create_block("heading_1", heading_text))
elif heading_level == 2:
blocks.append(self.create_block("heading_2", heading_text))
elif heading_level == 3:
blocks.append(self.create_block("heading_3", heading_text))
if heading_level in range(3):
blocks.append(self.create_block(f"heading_{heading_level+1}", heading_text))
else:
blocks.append(self.create_block("paragraph", text))
elif node.name == "h1":
@ -154,7 +152,7 @@ class AddContentToPage(LCToolComponent):
def is_table(self, text):
rows = text.split("\n")
if len(rows) < 2:
if len(rows) < MIN_ROWS_IN_TABLE:
return False
has_separator = False
@ -167,7 +165,7 @@ class AddContentToPage(LCToolComponent):
elif not cells:
return False
return has_separator and len(rows) >= 3
return has_separator
def process_list(self, node, list_type):
blocks = []
@ -191,7 +189,7 @@ class AddContentToPage(LCToolComponent):
if header_row or body_rows:
table_width = max(
len(header_row.find_all(["th", "td"])) if header_row else 0,
max(len(row.find_all(["th", "td"])) for row in body_rows),
*(len(row.find_all(["th", "td"])) for row in body_rows),
)
table_block = self.create_block("table", "", table_width=table_width, has_column_header=bool(header_row))

View file

@ -32,9 +32,7 @@ class ConversationChainComponent(LCChainComponent):
if isinstance(result, dict):
result = result.get(chain.output_key, "") # type: ignore
elif isinstance(result, str):
result = result
else:
elif not isinstance(result, str):
result = result.get("response")
result = str(result)
self.status = result

View file

@ -129,13 +129,13 @@ class GmailLoaderComponent(Component):
messages = thread["messages"]
response_email = None
for message in messages:
email_data = message["payload"]["headers"]
for _message in messages:
email_data = _message["payload"]["headers"]
for values in email_data:
if values["name"] == "Message-ID":
message_id = values["value"]
if message_id == in_reply_to:
response_email = message
response_email = _message
if response_email is None:
msg = "Response email not found in the thread."
raise ValueError(msg)

View file

@ -34,7 +34,7 @@ class EmbeddingSimilarityComponent(Component):
embedding_vectors: list[Data] = self.embedding_vectors
# Assert that the list contains exactly two Data objects
assert len(embedding_vectors) == 2, "Exactly two embedding vectors are required."
assert len(embedding_vectors) == 2, "Exactly two embedding vectors are required." # noqa: PLR2004
embedding_1 = np.array(embedding_vectors[0].data["embeddings"])
embedding_2 = np.array(embedding_vectors[1].data["embeddings"])

View file

@ -62,7 +62,7 @@ class HuggingFaceInferenceAPIEmbeddingsComponent(LCEmbeddingsModel):
)
raise ValueError(msg) from e
if response.status_code != 200:
if response.status_code != requests.codes.ok:
msg = f"HuggingFace health check failed: {response.status_code}"
raise ValueError(msg)
# returning True to solve linting error

View file

@ -76,7 +76,7 @@ class GroqModel(LCModelComponent):
return []
def update_build_config(self, build_config: dict, field_value: str, field_name: str | None = None):
if field_name == "groq_api_key" or field_name == "groq_api_base" or field_name == "model_name":
if field_name in ("groq_api_key", "groq_api_base", "model_name"):
models = self.get_models()
build_config["model_name"]["options"] = models
return build_config

View file

@ -7,6 +7,8 @@ from langflow.io import Output
from langflow.schema import Data
from langflow.schema.dotdict import dotdict
MAX_NUMBER_OF_FIELDS = 15
class CreateDataComponent(Component):
display_name: str = "Create Data"
@ -48,9 +50,11 @@ class CreateDataComponent(Component):
except ValueError:
return build_config
existing_fields = {}
if field_value_int > 15:
build_config["number_of_fields"]["value"] = 15
msg = "Number of fields cannot exceed 15. Try using a Component to combine two Data."
if field_value_int > MAX_NUMBER_OF_FIELDS:
build_config["number_of_fields"]["value"] = MAX_NUMBER_OF_FIELDS
msg = (
f"Number of fields cannot exceed {MAX_NUMBER_OF_FIELDS}. Try using a Component to combine two Data."
)
raise ValueError(msg)
if len(build_config) > len(default_keys):
# back up the existing template fields
@ -89,10 +93,10 @@ class CreateDataComponent(Component):
for value_dict in self._attributes.values():
if isinstance(value_dict, dict):
# Check if the value of the value_dict is a Data
value_dict = {
_value_dict = {
key: value.get_text() if isinstance(value, Data) else value for key, value in value_dict.items()
}
data.update(value_dict)
data.update(_value_dict)
return data
def validate_text_key(self):

View file

@ -66,7 +66,7 @@ class RunnableExecComponent(Component):
if output_key in result:
result_value = result.get(output_key)
elif len(result) == 2 and input_key in result:
elif len(result) == 2 and input_key in result: # noqa: PLR2004
# get the other key from the result dict
other_key = next(k for k in result if k != input_key)
if other_key == output_key:

View file

@ -7,6 +7,8 @@ from langflow.io import Output
from langflow.schema import Data
from langflow.schema.dotdict import dotdict
MAX_NUMBER_OF_FIELDS = 15
class UpdateDataComponent(Component):
display_name: str = "Update data"
@ -54,9 +56,11 @@ class UpdateDataComponent(Component):
except ValueError:
return build_config
existing_fields = {}
if field_value_int > 15:
build_config["number_of_fields"]["value"] = 15
msg = "Number of fields cannot exceed 15. Try using a Component to combine two Data."
if field_value_int > MAX_NUMBER_OF_FIELDS:
build_config["number_of_fields"]["value"] = MAX_NUMBER_OF_FIELDS
msg = (
f"Number of fields cannot exceed {MAX_NUMBER_OF_FIELDS}. Try using a Component to combine two Data."
)
raise ValueError(msg)
if len(build_config) > len(default_keys):
# back up the existing template fields
@ -96,10 +100,10 @@ class UpdateDataComponent(Component):
for value_dict in self._attributes.values():
if isinstance(value_dict, dict):
# Check if the value of the value_dict is a Data
value_dict = {
_value_dict = {
key: value.get_text() if isinstance(value, Data) else value for key, value in value_dict.items()
}
data.update(value_dict)
data.update(_value_dict)
return data
def validate_text_key(self, data: Data):

View file

@ -86,7 +86,7 @@ class PythonCodeStructuredTool(LCToolComponent):
if field_name is None:
return build_config
if field_name != "tool_code" and field_name != "tool_function":
if field_name not in ("tool_code", "tool_function"):
return build_config
try:

View file

@ -56,24 +56,15 @@ class MongoVectorStoreComponent(LCVectorStoreComponent):
else:
documents.append(_input)
if documents:
vector_store = MongoDBAtlasVectorSearch.from_documents(
documents=documents, embedding=self.embedding, collection=collection, index_name=self.index_name
)
else:
vector_store = MongoDBAtlasVectorSearch(
embedding=self.embedding,
collection=collection,
index_name=self.index_name,
)
else:
vector_store = MongoDBAtlasVectorSearch(
embedding=self.embedding,
collection=collection,
index_name=self.index_name,
if documents:
return MongoDBAtlasVectorSearch.from_documents(
documents=documents, embedding=self.embedding, collection=collection, index_name=self.index_name
)
return vector_store
return MongoDBAtlasVectorSearch(
embedding=self.embedding,
collection=collection,
index_name=self.index_name,
)
def search_documents(self) -> list[Data]:
from bson.objectid import ObjectId

View file

@ -352,8 +352,8 @@ class CodeParser:
methods=[],
init=None,
)
for node in nodes:
self.process_class_node(node, class_details)
for _node in nodes:
self.process_class_node(_node, class_details)
self.data["classes"].append(class_details.model_dump())
def process_class_node(self, node, class_details):

View file

@ -42,7 +42,7 @@ _ComponentToolkit = None
def _get_component_toolkit():
global _ComponentToolkit
global _ComponentToolkit # noqa: PLW0603
if _ComponentToolkit is None:
from langflow.base.tools.component_tool import ComponentToolkit

View file

@ -116,8 +116,8 @@ class DirectoryReader:
except UnicodeDecodeError:
# This is happening in Windows, so we need to open the file in binary mode
# The file is always just a python file, so we can safely read it as utf-8
with _file_path.open("rb") as file:
return file.read().decode("utf-8")
with _file_path.open("rb") as f:
return f.read().decode("utf-8")
def get_files(self):
"""

View file

@ -44,15 +44,15 @@ def add_output_types(frontend_node: CustomComponentFrontendNode, return_types: l
},
)
if return_type is str:
return_type = "Text"
_return_type = "Text"
elif hasattr(return_type, "__name__"):
return_type = return_type.__name__
_return_type = return_type.__name__
elif hasattr(return_type, "__class__"):
return_type = return_type.__class__.__name__
_return_type = return_type.__class__.__name__
else:
return_type = str(return_type)
_return_type = str(return_type)
frontend_node.add_output_type(return_type)
frontend_node.add_output_type(_return_type)
def reorder_fields(frontend_node: CustomComponentFrontendNode, field_order: list[str]):
@ -224,19 +224,18 @@ def add_extra_fields(frontend_node, field_config, function_args):
config,
)
if "kwargs" in function_args_names and not all(key in function_args_names for key in field_config):
for field_name, field_config in _field_config.copy().items():
if "name" not in field_config or field_name == "code":
for field_name, config in _field_config.items():
if "name" not in config or field_name == "code":
continue
config = _field_config.get(field_name, {})
config = config.model_dump() if isinstance(config, BaseModel) else config
field_name, field_type, field_value, field_required = get_field_properties(extra_field=config)
_config = config.model_dump() if isinstance(config, BaseModel) else config
_field_name, field_type, field_value, field_required = get_field_properties(extra_field=_config)
frontend_node = add_new_custom_field(
frontend_node,
field_name,
_field_name,
field_type,
field_value,
field_required,
config,
_config,
)

View file

@ -30,10 +30,11 @@ class EventManager:
raise ValueError(msg)
# Check if it has `self, event_type and data`
sig = inspect.signature(callback)
if len(sig.parameters) != 3:
parameters = ["manager", "event_type", "data"]
if len(sig.parameters) != len(parameters):
msg = "Callback must have exactly 3 parameters"
raise ValueError(msg)
if not all(param.name in ["manager", "event_type", "data"] for param in sig.parameters.values()):
if not all(param.name in parameters for param in sig.parameters.values()):
msg = "Callback must have exactly 3 parameters: manager, event_type, and data"
raise ValueError(msg)

Some files were not shown because too many files have changed in this diff Show more