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:
Harshit28j
2026-03-11 16:42:35 +05:30
co-authored by Claude Opus 4.6
parent 9200b28078
commit 3cc2ccec4a
2 changed files with 21 additions and 5 deletions
+9 -5
View File
@@ -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()