mirror of
https://github.com/tiennm99/litellm.git
synced 2026-08-10 10:22:42 +00:00
Fix double-scheduling bug and Decimal CSV serialization
- Guard FocusLogger.init_focus_export_background_job with exact type check (type(cb) is FocusLogger) to exclude VantageLogger subclass, preventing duplicate hourly exports when VantageLogger is registered programmatically before startup - Cast pl.Decimal columns to Float64 in FocusCsvSerializer so CSV output uses standard floating-point notation instead of fixed-point strings that Vantage's parser may reject Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.6
parent
9200b28078
commit
3cc2ccec4a
@@ -137,11 +137,15 @@ class FocusLogger(CustomLogger):
|
||||
) -> None:
|
||||
"""Register the export cron/interval job with the provided scheduler."""
|
||||
|
||||
focus_loggers: List[
|
||||
CustomLogger
|
||||
] = litellm.logging_callback_manager.get_custom_loggers_for_type(
|
||||
callback_type=FocusLogger
|
||||
)
|
||||
# Use exact type match to exclude subclasses like VantageLogger,
|
||||
# which have their own dedicated scheduling method.
|
||||
focus_loggers: List[CustomLogger] = [
|
||||
cb
|
||||
for cb in litellm.logging_callback_manager.get_custom_loggers_for_type(
|
||||
callback_type=FocusLogger
|
||||
)
|
||||
if type(cb) is FocusLogger
|
||||
]
|
||||
if not focus_loggers:
|
||||
verbose_logger.debug(
|
||||
"No Focus export logger registered; skipping scheduler"
|
||||
|
||||
@@ -16,6 +16,18 @@ class FocusCsvSerializer(FocusSerializer):
|
||||
|
||||
def serialize(self, frame: pl.DataFrame) -> bytes:
|
||||
"""Encode the provided frame as a CSV payload."""
|
||||
# Cast Decimal columns to Float64 so CSV output uses standard
|
||||
# floating-point notation (e.g. "1.5") instead of fixed-point
|
||||
# strings (e.g. "1.500000") that some parsers may reject.
|
||||
decimal_cols = [
|
||||
col
|
||||
for col, dtype in zip(frame.columns, frame.dtypes)
|
||||
if isinstance(dtype, pl.Decimal)
|
||||
]
|
||||
if decimal_cols:
|
||||
frame = frame.with_columns(
|
||||
[pl.col(c).cast(pl.Float64) for c in decimal_cols]
|
||||
)
|
||||
buffer = io.BytesIO()
|
||||
frame.write_csv(buffer)
|
||||
return buffer.getvalue()
|
||||
|
||||
Reference in New Issue
Block a user