fix: truncate transaction and vertex messages (#7893)

* add pyinstrument and fastapi wrapper

* Truncate vertex build responses

* Truncate vertex response and transactions

* [autofix.ci] apply automated fixes

* Update test for vertex response structure to reflect new truncation logic

* Refactor profiling middleware to use environment variable for configuration

* Update test for vertex response structure to correct truncation logic

* move pyinstrument to dev dependencies

* Update serialization test to include max_items parameter for list truncation

* remove profiling from this PR, fix constants

* [autofix.ci] apply automated fixes

* Add asyncio configuration options to pyproject.toml

---------

Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
Co-authored-by: Gabriel Luiz Freitas Almeida <gabriel@langflow.org>
This commit is contained in:
Jordan Frazier 2025-05-05 17:03:13 -07:00 committed by GitHub
commit 2c6ea9c98f
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
7 changed files with 2915 additions and 2915 deletions

View file

@ -26,7 +26,6 @@ from langflow.services.database.models.flow import FlowCreate, FlowRead
from langflow.services.database.models.user import UserRead from langflow.services.database.models.user import UserRead
from langflow.services.settings.feature_flags import FeatureFlags from langflow.services.settings.feature_flags import FeatureFlags
from langflow.services.tracing.schema import Log from langflow.services.tracing.schema import Log
from langflow.utils.util_strings import truncate_long_strings
class BuildStatus(Enum): class BuildStatus(Enum):
@ -310,8 +309,7 @@ class VertexBuildResponse(BaseModel):
@field_serializer("data") @field_serializer("data")
def serialize_data(self, data: ResultDataResponse) -> dict: def serialize_data(self, data: ResultDataResponse) -> dict:
data_dict = data.model_dump() if isinstance(data, BaseModel) else data return serialize(data, max_length=MAX_TEXT_LENGTH, max_items=MAX_ITEMS_LENGTH)
return truncate_long_strings(data_dict)
class VerticesBuiltResponse(BaseModel): class VerticesBuiltResponse(BaseModel):

View file

@ -12,6 +12,7 @@ from langflow.interface.utils import extract_input_variables_from_prompt
from langflow.schema.data import Data from langflow.schema.data import Data
from langflow.schema.message import Message from langflow.schema.message import Message
from langflow.serialization import serialize from langflow.serialization import serialize
from langflow.serialization.constants import MAX_ITEMS_LENGTH, MAX_TEXT_LENGTH
from langflow.services.database.models.transactions.crud import log_transaction as crud_log_transaction from langflow.services.database.models.transactions.crud import log_transaction as crud_log_transaction
from langflow.services.database.models.transactions.model import TransactionBase from langflow.services.database.models.transactions.model import TransactionBase
from langflow.services.database.models.vertex_builds.crud import log_vertex_build as crud_log_vertex_build from langflow.services.database.models.vertex_builds.crud import log_vertex_build as crud_log_vertex_build
@ -142,8 +143,8 @@ async def log_transaction(
transaction = TransactionBase( transaction = TransactionBase(
vertex_id=source.id, vertex_id=source.id,
target_id=target.id if target else None, target_id=target.id if target else None,
inputs=inputs, inputs=serialize(inputs, max_length=MAX_TEXT_LENGTH, max_items=MAX_ITEMS_LENGTH),
outputs=outputs, outputs=serialize(outputs, max_length=MAX_TEXT_LENGTH, max_items=MAX_ITEMS_LENGTH),
status=status, status=status,
error=error, error=error,
flow_id=flow_id if isinstance(flow_id, UUID) else UUID(flow_id), flow_id=flow_id if isinstance(flow_id, UUID) else UUID(flow_id),
@ -175,10 +176,8 @@ async def log_vertex_build(
id=vertex_id, id=vertex_id,
valid=valid, valid=valid,
params=str(params) if params else None, params=str(params) if params else None,
# Serialize data using our custom serializer data=serialize(data, max_length=MAX_TEXT_LENGTH, max_items=MAX_ITEMS_LENGTH),
data=serialize(data), artifacts=serialize(artifacts, max_length=MAX_TEXT_LENGTH, max_items=MAX_ITEMS_LENGTH),
# Serialize artifacts using our custom serializer
artifacts=serialize(artifacts) if artifacts else None,
) )
async with session_getter(get_db_service()) as session: async with session_getter(get_db_service()) as session:
inserted = await crud_log_vertex_build(session, vertex_build) inserted = await crud_log_vertex_build(session, vertex_build)

View file

@ -207,7 +207,11 @@ def create_app():
__version__ = get_version_info()["version"] __version__ = get_version_info()["version"]
configure() configure()
lifespan = get_lifespan(version=__version__) lifespan = get_lifespan(version=__version__)
app = FastAPI(lifespan=lifespan, title="Langflow", version=__version__) app = FastAPI(
title="Langflow",
version=__version__,
lifespan=lifespan,
)
app.add_middleware( app.add_middleware(
ContentSizeLimitMiddleware, ContentSizeLimitMiddleware,
) )

View file

@ -1,2 +1,2 @@
MAX_TEXT_LENGTH = 20000 MAX_TEXT_LENGTH = 2000
MAX_ITEMS_LENGTH = 1000 MAX_ITEMS_LENGTH = 100

View file

@ -63,7 +63,7 @@ def test_vertex_response_structure_when_truncate_applies():
("size", "expected"), ("size", "expected"),
[ [
(0, 0), (0, 0),
(42, 42), (8, 8),
(MAX_ITEMS_LENGTH, MAX_ITEMS_LENGTH), (MAX_ITEMS_LENGTH, MAX_ITEMS_LENGTH),
(MAX_ITEMS_LENGTH + 1000, MAX_ITEMS_LENGTH + 1), (MAX_ITEMS_LENGTH + 1000, MAX_ITEMS_LENGTH + 1),
(MAX_ITEMS_LENGTH + 2000, MAX_ITEMS_LENGTH + 1), (MAX_ITEMS_LENGTH + 2000, MAX_ITEMS_LENGTH + 1),

View file

@ -92,7 +92,7 @@ class TestSerializationHypothesis:
@settings(max_examples=100) @settings(max_examples=100)
@given(lst=list_strategy) @given(lst=list_strategy)
def test_list_truncation(self, lst: list) -> None: def test_list_truncation(self, lst: list) -> None:
result: list = serialize(lst) result: list = serialize(lst, max_items=MAX_ITEMS_LENGTH)
if len(lst) > MAX_ITEMS_LENGTH: if len(lst) > MAX_ITEMS_LENGTH:
assert len(result) == MAX_ITEMS_LENGTH + 1 assert len(result) == MAX_ITEMS_LENGTH + 1
assert f"... [truncated {len(lst) - MAX_ITEMS_LENGTH} items]" in result assert f"... [truncated {len(lst) - MAX_ITEMS_LENGTH} items]" in result

5801
uv.lock generated

File diff suppressed because it is too large Load diff