This mapping has 1 multi-map group: several pairings are equally correct there. The code view shows one arbitrary valid pairing, not the only one.

Before

1import asyncio
2import json
3import logging
4import os
5import sys
6from collections import deque
7from pathlib import Path
8from threading import Lock, Semaphore
9from typing import TypedDict
10
11import orjson
12from loguru import _defaults, logger
13from loguru._error_interceptor import ErrorInterceptor
14from loguru._file_sink import FileSink
15from loguru._simple_sinks import AsyncSink
16from platformdirs import user_cache_dir
17from rich.logging import RichHandler
18from typing_extensions import NotRequired, override
19
20from langflow.settings import DEV
21
…lines 22–150 unchanged (129 lines)
151 log_file: NotRequired[Path]
152 disable: NotRequired[bool]
153 log_env: NotRequired[str]
154 log_format: NotRequired[str]
155
156
157class AsyncFileSink(AsyncSink):
158 def __init__(self, file):
159 self._sink = FileSink(
160 path=file,
161 rotation="10 MB", # Log rotation based on file size
162 delay=True,
163 )
164 super().__init__(self.write_async, None, ErrorInterceptor(_defaults.LOGURU_CATCH, -1))
165
166 async def complete(self):
167 await asyncio.to_thread(self._sink.stop)
168 for task in self._tasks:
169 await self._complete_task(task)
170
171 async def write_async(self, message):
172 await asyncio.to_thread(self._sink.write, message)
173
174
175def is_valid_log_format(format_string) -> bool:
176 """Validates a logging format string by attempting to format it with a dummy LogRecord.
177
178 Args:
…lines 179–200 unchanged (22 lines)
201 log_level: str | None = None,
202 log_file: Path | None = None,
203 disable: bool | None = False,
204 log_env: str | None = None,
205 log_format: str | None = None,
206 async_file: bool = False,
207) -> None:
208 if disable and log_level is None and log_file is None:
209 logger.disable("langflow")
210 if os.getenv("LANGFLOW_LOG_LEVEL", "").upper() in VALID_LOG_LEVELS and log_level is None:
211 log_level = os.getenv("LANGFLOW_LOG_LEVEL")
212 if log_level is None:
213 log_level = "ERROR"
…lines 214–248 unchanged (35 lines)
249
250 if not log_file:
251 cache_dir = Path(user_cache_dir("langflow"))
252 logger.debug(f"Cache directory: {cache_dir}")
253 log_file = cache_dir / "langflow.log"
254 logger.debug(f"Log file: {log_file}")
255 try:
256 logger.add(
257 sink=AsyncFileSink(log_file) if async_file else log_file,
258 level=log_level.upper(),
259 format=log_format,
260 serialize=True,
261 )
262 except Exception: # noqa: BLE001
263 logger.exception("Error setting up log file")
264
265 if log_buffer.enabled():
266 logger.add(sink=log_buffer.write, format="{time} {level} {message}", serialize=True)
267
…lines 268–307 unchanged (40 lines)

After

1import json
2import logging
3import os
4import sys
5from collections import deque
6from pathlib import Path
7from threading import Lock, Semaphore
8from typing import TypedDict
9
10import orjson
11from loguru import logger
12from platformdirs import user_cache_dir
13from rich.logging import RichHandler
14from typing_extensions import NotRequired, override
15
16from langflow.settings import DEV
17
…lines 18–144 unchanged (127 lines)
145class LogConfig(TypedDict):
146 log_level: NotRequired[str]
147 log_file: NotRequired[Path]
148 disable: NotRequired[bool]
149 log_env: NotRequired[str]
150 log_format: NotRequired[str]
151
152
153def is_valid_log_format(format_string) -> bool:
154 """Validates a logging format string by attempting to format it with a dummy LogRecord.
155
156 Args:
157 format_string (str): The format string to validate.
…lines 158–178 unchanged (21 lines)
179 log_level: str | None = None,
180 log_file: Path | None = None,
181 disable: bool | None = False,
182 log_env: str | None = None,
183 log_format: str | None = None,
184 async_file: bool = False,
185 log_rotation: str | None = None,
186) -> None:
187 if disable and log_level is None and log_file is None:
188 logger.disable("langflow")
189 if os.getenv("LANGFLOW_LOG_LEVEL", "").upper() in VALID_LOG_LEVELS and log_level is None:
190 log_level = os.getenv("LANGFLOW_LOG_LEVEL")
191 if log_level is None:
…lines 192–228 unchanged (37 lines)
229 if not log_file:
230 cache_dir = Path(user_cache_dir("langflow"))
231 logger.debug(f"Cache directory: {cache_dir}")
232 log_file = cache_dir / "langflow.log"
233 logger.debug(f"Log file: {log_file}")
234
235 if os.getenv("LANGFLOW_LOG_ROTATION") and log_rotation is None:
236 log_rotation = os.getenv("LANGFLOW_LOG_ROTATION")
237 elif log_rotation is None:
238 log_rotation = "1 day"
239
240 try:
241 logger.add(
242 sink=log_file,
243 level=log_level.upper(),
244 format=log_format,
245 serialize=True,
246 enqueue=async_file,
247 rotation=log_rotation,
248 )
249 except Exception: # noqa: BLE001
250 logger.exception("Error setting up log file")
251
252 if log_buffer.enabled():
253 logger.add(sink=log_buffer.write, format="{time} {level} {message}", serialize=True)
…lines 254–294 unchanged (41 lines)

Before

module
import_statement
import "import"
dotted_name
identifier "asyncio"
import_statement
import "import"
dotted_name
identifier "json"
import_statement
import "import"
dotted_name
identifier "logging"
import_statement
import "import"
dotted_name
identifier "os"
import_statement
import "import"
dotted_name
identifier "sys"
import_from_statement
from "from"
dotted_name
identifier "collections"
import "import"
dotted_name
identifier "deque"
import_from_statement
from "from"
dotted_name
identifier "pathlib"
import "import"
dotted_name
identifier "Path"
import_from_statement
from "from"
dotted_name
identifier "threading"
import "import"
dotted_name
identifier "Lock"
, ","
dotted_name
identifier "Semaphore"
import_from_statement
from "from"
dotted_name
identifier "typing"
import "import"
dotted_name
identifier "TypedDict"
import_statement
import "import"
dotted_name
identifier "orjson"
import_from_statement
from "from"
dotted_name
identifier "loguru"
import "import"
dotted_name
identifier "_defaults"
, ","
dotted_name
identifier "logger"
import_from_statement
from "from"
dotted_name
identifier "loguru"
. "."
identifier "_error_interceptor"
import "import"
dotted_name
identifier "ErrorInterceptor"
import_from_statement
from "from"
dotted_name
identifier "loguru"
. "."
identifier "_file_sink"
import "import"
dotted_name
identifier "FileSink"
import_from_statement
from "from"
dotted_name
identifier "loguru"
. "."
identifier "_simple_sinks"
import "import"
dotted_name
identifier "AsyncSink"
import_from_statement
from "from"
dotted_name
identifier "platformdirs"
import "import"
dotted_name
identifier "user_cache_dir"
import_from_statement
from "from"
dotted_name
identifier "rich"
. "."
identifier "logging"
import "import"
dotted_name
identifier "RichHandler"
import_from_statement
from "from"
dotted_name
identifier "typing_extensions"
import "import"
dotted_name
identifier "NotRequired"
, ","
dotted_name
identifier "override"
import_from_statement
from "from"
dotted_name
identifier "langflow"
. "."
identifier "settings"
import "import"
dotted_name
identifier "DEV"
expression_statement (+36 nodes collapsed)
comment "# Human-readable"
expression_statement
assignment
identifier "DEFAULT_LOG_FORMAT"
= "="
parenthesized_expression
( "("
string
string_start "\""
string_content "<green>{time:YYYY-MM-DD HH:mm:ss}</green> - <level>{level: <"...
string_end "\""
) ")"
class_definition (+896 nodes collapsed)
comment "# log buffer for capturing log messages"
expression_statement
assignment
identifier "log_buffer"
= "="
call
identifier "SizedLogBuffer"
argument_list
( "("
) ")"
function_definition (+97 nodes collapsed)
function_definition (+59 nodes collapsed)
class_definition (+69 nodes collapsed)
class_definition
class "class"
identifier "AsyncFileSink"
argument_list
( "("
identifier "AsyncSink"
) ")"
: ":"
block
function_definition
def "def"
identifier "__init__"
parameters
( "("
identifier "self"
, ","
identifier "file"
) ")"
: ":"
block
expression_statement
assignment
attribute
identifier "self"
. "."
identifier "_sink"
= "="
call
identifier "FileSink"
argument_list
( "("
keyword_argument
identifier "path"
= "="
identifier "file"
, ","
keyword_argument
identifier "rotation"
= "="
string
string_start "\""
string_content "10 MB"
string_end "\""
, ","
comment "# Log rotation based on file size"
keyword_argument
identifier "delay"
= "="
true "True"
, ","
) ")"
expression_statement
call
attribute
call
identifier "super"
argument_list
( "("
) ")"
. "."
identifier "__init__"
argument_list
( "("
attribute
identifier "self"
. "."
identifier "write_async"
, ","
none "None"
, ","
call
identifier "ErrorInterceptor"
argument_list
( "("
attribute
identifier "_defaults"
. "."
identifier "LOGURU_CATCH"
, ","
unary_operator
- "-"
integer "1"
) ")"
) ")"
function_definition
async "async"
def "def"
identifier "complete"
parameters
( "("
identifier "self"
) ")"
: ":"
block
expression_statement
await
await "await"
call
attribute
identifier "asyncio"
. "."
identifier "to_thread"
argument_list
( "("
attribute
attribute
identifier "self"
. "."
identifier "_sink"
. "."
identifier "stop"
) ")"
for_statement
for "for"
identifier "task"
in "in"
attribute
identifier "self"
. "."
identifier "_tasks"
: ":"
block
expression_statement
await
await "await"
call
attribute
identifier "self"
. "."
identifier "_complete_task"
argument_list
( "("
identifier "task"
) ")"
function_definition
async "async"
def "def"
identifier "write_async"
parameters
( "("
identifier "self"
, ","
identifier "message"
) ")"
: ":"
block
expression_statement
await
await "await"
call
attribute
identifier "asyncio"
. "."
identifier "to_thread"
argument_list
( "("
attribute
attribute
identifier "self"
. "."
identifier "_sink"
. "."
identifier "write"
, ","
identifier "message"
) ")"
function_definition (+134 nodes collapsed)
function_definition
def "def"
identifier "configure"
parameters
( "("
keyword_separator
* "*"
, ","
typed_default_parameter
identifier "log_level"
: ":"
type
binary_operator
identifier "str"
| "|"
none "None"
= "="
none "None"
, ","
typed_default_parameter
identifier "log_file"
: ":"
type
binary_operator
identifier "Path"
| "|"
none "None"
= "="
none "None"
, ","
typed_default_parameter
identifier "disable"
: ":"
type
binary_operator
identifier "bool"
| "|"
none "None"
= "="
false "False"
, ","
typed_default_parameter
identifier "log_env"
: ":"
type
binary_operator
identifier "str"
| "|"
none "None"
= "="
none "None"
, ","
typed_default_parameter
identifier "log_format"
: ":"
type
binary_operator
identifier "str"
| "|"
none "None"
= "="
none "None"
, ","
typed_default_parameter
identifier "async_file"
: ":"
type
identifier "bool"
= "="
false "False"
, ","
) ")"
-> "->"
type
none "None"
: ":"
block
if_statement (+30 nodes collapsed)
if_statement (+52 nodes collapsed)
if_statement
if "if"
comparison_operator
identifier "log_level"
is "is"
none "None"
: ":"
block
expression_statement
assignment
identifier "log_level"
= "="
string
string_start "\""
string_content "ERROR"
string_end "\""
if_statement (+43 nodes collapsed)
if_statement (+28 nodes collapsed)
expression_statement
call
attribute
identifier "logger"
. "."
identifier "remove"
argument_list
( "("
) ")"
comment "# Remove default handlers"
expression_statement
call
attribute
identifier "logger"
. "."
identifier "patch"
argument_list
( "("
identifier "patching"
) ")"
if_statement
if "if"
boolean_operator (+30 nodes collapsed)
: ":"
block (+27 nodes collapsed)
elif_clause (+39 nodes collapsed)
else_clause
else "else"
: ":"
block
if_statement (+38 nodes collapsed)
if_statement (+23 nodes collapsed)
comment "# pretty print to rich stdout development-friendly but poor "...
comment "# suggest directly print to stdout in production"
expression_statement (+34 nodes collapsed)
if_statement (+111 nodes collapsed)
if_statement (+70 nodes collapsed)
try_statement
try "try"
: ":"
block
expression_statement
call
attribute
identifier "logger"
. "."
identifier "add"
argument_list
( "("
keyword_argument
identifier "sink"
= "="
conditional_expression
call
identifier "AsyncFileSink"
argument_list
( "("
identifier "log_file" any 2:1
) ")"
if "if"
identifier "async_file"
else "else"
identifier "log_file" any 2:1
, ","
keyword_argument
identifier "level"
= "="
call
attribute
identifier "log_level"
. "."
identifier "upper"
argument_list
( "("
) ")"
, ","
keyword_argument
identifier "format"
= "="
identifier "log_format"
, ","
keyword_argument
identifier "serialize"
= "="
true "True"
, ","
) ")"
except_clause
except "except"
identifier "Exception"
: ":"
comment "# noqa: BLE001"
block
expression_statement
call
attribute
identifier "logger"
. "."
identifier "exception"
argument_list
( "("
string
string_start "\""
string_content "Error setting up log file"
string_end "\""
) ")"
if_statement (+41 nodes collapsed)
expression_statement
call
attribute
identifier "logger"
. "."
identifier "debug"
argument_list
( "("
string
string_start "f\""
string_content "Logger set up with log level: "
interpolation
{ "{"
identifier "log_level"
} "}"
string_end "\""
) ")"
expression_statement
call
identifier "setup_uvicorn_logger"
argument_list
( "("
) ")"
expression_statement
call
identifier "setup_gunicorn_logger"
argument_list
( "("
) ")"
function_definition (+98 nodes collapsed)
function_definition (+63 nodes collapsed)
class_definition (+165 nodes collapsed)

After

module
import_statement
import "import"
dotted_name
identifier "json"
import_statement
import "import"
dotted_name
identifier "logging"
import_statement
import "import"
dotted_name
identifier "os"
import_statement
import "import"
dotted_name
identifier "sys"
import_from_statement
from "from"
dotted_name
identifier "collections"
import "import"
dotted_name
identifier "deque"
import_from_statement
from "from"
dotted_name
identifier "pathlib"
import "import"
dotted_name
identifier "Path"
import_from_statement
from "from"
dotted_name
identifier "threading"
import "import"
dotted_name
identifier "Lock"
, ","
dotted_name
identifier "Semaphore"
import_from_statement
from "from"
dotted_name
identifier "typing"
import "import"
dotted_name
identifier "TypedDict"
import_statement
import "import"
dotted_name
identifier "orjson"
import_from_statement
from "from"
dotted_name
identifier "loguru"
import "import"
dotted_name
identifier "logger"
import_from_statement
from "from"
dotted_name
identifier "platformdirs"
import "import"
dotted_name
identifier "user_cache_dir"
import_from_statement
from "from"
dotted_name
identifier "rich"
. "."
identifier "logging"
import "import"
dotted_name
identifier "RichHandler"
import_from_statement
from "from"
dotted_name
identifier "typing_extensions"
import "import"
dotted_name
identifier "NotRequired"
, ","
dotted_name
identifier "override"
import_from_statement
from "from"
dotted_name
identifier "langflow"
. "."
identifier "settings"
import "import"
dotted_name
identifier "DEV"
expression_statement (+36 nodes collapsed)
comment "# Human-readable"
expression_statement
assignment
identifier "DEFAULT_LOG_FORMAT"
= "="
parenthesized_expression
( "("
string
string_start "\""
string_content "<green>{time:YYYY-MM-DD HH:mm:ss}</green> - <level>{level: <"...
string_end "\""
) ")"
class_definition (+896 nodes collapsed)
comment "# log buffer for capturing log messages"
expression_statement
assignment
identifier "log_buffer"
= "="
call
identifier "SizedLogBuffer"
argument_list
( "("
) ")"
function_definition (+97 nodes collapsed)
function_definition (+59 nodes collapsed)
class_definition (+69 nodes collapsed)
function_definition (+134 nodes collapsed)
function_definition
def "def"
identifier "configure"
parameters
( "("
keyword_separator
* "*"
, ","
typed_default_parameter
identifier "log_level"
: ":"
type
binary_operator
identifier "str"
| "|"
none "None"
= "="
none "None"
, ","
typed_default_parameter
identifier "log_file"
: ":"
type
binary_operator
identifier "Path"
| "|"
none "None"
= "="
none "None"
, ","
typed_default_parameter
identifier "disable"
: ":"
type
binary_operator
identifier "bool"
| "|"
none "None"
= "="
false "False"
, ","
typed_default_parameter
identifier "log_env"
: ":"
type
binary_operator
identifier "str"
| "|"
none "None"
= "="
none "None"
, ","
typed_default_parameter
identifier "log_format"
: ":"
type
binary_operator
identifier "str"
| "|"
none "None"
= "="
none "None"
, ","
typed_default_parameter
identifier "async_file"
: ":"
type
identifier "bool"
= "="
false "False"
, ","
typed_default_parameter
identifier "log_rotation"
: ":"
type
binary_operator
identifier "str"
| "|"
none "None"
= "="
none "None"
, ","
) ")"
-> "->"
type
none "None"
: ":"
block
if_statement (+30 nodes collapsed)
if_statement (+52 nodes collapsed)
if_statement
if "if"
comparison_operator
identifier "log_level"
is "is"
none "None"
: ":"
block
expression_statement
assignment
identifier "log_level"
= "="
string
string_start "\""
string_content "ERROR"
string_end "\""
if_statement (+43 nodes collapsed)
if_statement (+28 nodes collapsed)
expression_statement
call
attribute
identifier "logger"
. "."
identifier "remove"
argument_list
( "("
) ")"
comment "# Remove default handlers"
expression_statement
call
attribute
identifier "logger"
. "."
identifier "patch"
argument_list
( "("
identifier "patching"
) ")"
if_statement
if "if"
boolean_operator (+30 nodes collapsed)
: ":"
block (+27 nodes collapsed)
elif_clause (+39 nodes collapsed)
else_clause
else "else"
: ":"
block
if_statement (+38 nodes collapsed)
if_statement (+23 nodes collapsed)
comment "# pretty print to rich stdout development-friendly but poor "...
comment "# suggest directly print to stdout in production"
expression_statement (+34 nodes collapsed)
if_statement (+111 nodes collapsed)
if_statement (+70 nodes collapsed)
if_statement
if "if"
boolean_operator
call
attribute
identifier "os"
. "."
identifier "getenv"
argument_list
( "("
string
string_start "\""
string_content "LANGFLOW_LOG_ROTATION"
string_end "\""
) ")"
and "and"
comparison_operator
identifier "log_rotation"
is "is"
none "None"
: ":"
block
expression_statement
assignment
identifier "log_rotation"
= "="
call
attribute
identifier "os"
. "."
identifier "getenv"
argument_list
( "("
string
string_start "\""
string_content "LANGFLOW_LOG_ROTATION"
string_end "\""
) ")"
elif_clause
elif "elif"
comparison_operator
identifier "log_rotation"
is "is"
none "None"
: ":"
block
expression_statement
assignment
identifier "log_rotation"
= "="
string
string_start "\""
string_content "1 day"
string_end "\""
try_statement
try "try"
: ":"
block
expression_statement
call
attribute
identifier "logger"
. "."
identifier "add"
argument_list
( "("
keyword_argument
identifier "sink"
= "="
identifier "log_file" any 2:1
, ","
keyword_argument
identifier "level"
= "="
call
attribute
identifier "log_level"
. "."
identifier "upper"
argument_list
( "("
) ")"
, ","
keyword_argument
identifier "format"
= "="
identifier "log_format"
, ","
keyword_argument
identifier "serialize"
= "="
true "True"
, ","
keyword_argument
identifier "enqueue"
= "="
identifier "async_file"
, ","
keyword_argument
identifier "rotation"
= "="
identifier "log_rotation"
, ","
) ")"
except_clause
except "except"
identifier "Exception"
: ":"
comment "# noqa: BLE001"
block
expression_statement
call
attribute
identifier "logger"
. "."
identifier "exception"
argument_list
( "("
string
string_start "\""
string_content "Error setting up log file"
string_end "\""
) ")"
if_statement (+41 nodes collapsed)
expression_statement
call
attribute
identifier "logger"
. "."
identifier "debug"
argument_list
( "("
string
string_start "f\""
string_content "Logger set up with log level: "
interpolation
{ "{"
identifier "log_level"
} "}"
string_end "\""
) ")"
expression_statement
call
identifier "setup_uvicorn_logger"
argument_list
( "("
) ")"
expression_statement
call
identifier "setup_gunicorn_logger"
argument_list
( "("
) ")"
function_definition (+98 nodes collapsed)
function_definition (+63 nodes collapsed)
class_definition (+165 nodes collapsed)