diff --git a/langfuse/_client/environment_variables.py b/langfuse/_client/environment_variables.py index b149127c8..e78604f9b 100644 --- a/langfuse/_client/environment_variables.py +++ b/langfuse/_client/environment_variables.py @@ -94,4 +94,19 @@ Float between 0 and 1 indicating the sample rate of traces to bet sent to Langfuse servers. **Default value**: ``1.0`` + +""" +LANGFUSE_OBSERVE_DECORATOR_IO_CAPTURE_ENABLED = ( + "LANGFUSE_OBSERVE_DECORATOR_IO_CAPTURE_ENABLED" +) +""" +.. envvar: LANGFUSE_OBSERVE_DECORATOR_IO_CAPTURE_ENABLED + +Default capture of function args, kwargs and return value when using the @observe decorator. + +Having default IO capture enabled for observe decorated function may have a performance impact on your application +if large or deeply nested objects are attempted to be serialized. Set this value to `False` and use manual +input/output setting on your observation to avoid this. + +**Default value**: ``True`` """ diff --git a/langfuse/_client/observe.py b/langfuse/_client/observe.py index 97eb91a71..8416ffd46 100644 --- a/langfuse/_client/observe.py +++ b/langfuse/_client/observe.py @@ -1,6 +1,7 @@ import asyncio import inspect import logging +import os from functools import wraps from typing import ( Any, @@ -20,6 +21,9 @@ from typing_extensions import ParamSpec +from langfuse._client.environment_variables import ( + LANGFUSE_OBSERVE_DECORATOR_IO_CAPTURE_ENABLED, +) from langfuse._client.get_client import get_client from langfuse._client.span import LangfuseGeneration, LangfuseSpan from langfuse.types import TraceContext @@ -141,6 +145,10 @@ def sub_process(): - For async functions, the decorator returns an async function wrapper. - For sync functions, the decorator returns a synchronous wrapper. """ + function_io_capture_enabled = ( + os.environ.get(LANGFUSE_OBSERVE_DECORATOR_IO_CAPTURE_ENABLED, "True") + .lower() not in ("false", "0") + ) def decorator(func: F) -> F: return ( @@ -148,8 +156,8 @@ def decorator(func: F) -> F: func, name=name, as_type=as_type, - capture_input=capture_input, - capture_output=capture_output, + capture_input=function_io_capture_enabled and capture_input, + capture_output=function_io_capture_enabled and capture_output, transform_to_string=transform_to_string, ) if asyncio.iscoroutinefunction(func) @@ -157,8 +165,8 @@ def decorator(func: F) -> F: func, name=name, as_type=as_type, - capture_input=capture_input, - capture_output=capture_output, + capture_input=function_io_capture_enabled and capture_input, + capture_output=function_io_capture_enabled and capture_output, transform_to_string=transform_to_string, ) )