mirror of
https://github.com/BerriAI/litellm.git
synced 2026-09-08 22:21:35 +00:00
fix(cost): treat an equal-ended off-peak window as the whole day
A window whose start equals its end is the natural way to spell off-peak all day, and the docstring's promise that a window may wrap past midnight invites it. It took the non-wrap branch instead, where start <= now < end can never hold, so it matched nothing. It parses cleanly, so it never reached the branch that ignores malformed windows: no exception, no log, and the model billed at standard rates around the clock while the config said otherwise. Let equality fall through to the wrap branch, which covers every instant, and say so in the docstring. Reported by @xyzs996 in review.
This commit is contained in:
parent
4f174ffdd1
commit
27aefade5f
2 changed files with 16 additions and 2 deletions
|
|
@ -296,7 +296,8 @@ def _is_within_off_peak_window(off_peak_hours_utc: str | Sequence[str], current_
|
|||
|
||||
off_peak_hours_utc is a "HH:MM-HH:MM" string in UTC, or a list of such strings for providers
|
||||
with multiple daily windows (e.g. ["16:30-00:30", "04:00-06:00"]). A window may wrap past
|
||||
midnight. The start is inclusive and the end is exclusive; malformed windows are ignored.
|
||||
midnight, and a window whose start equals its end covers the whole day. The start is
|
||||
inclusive and the end is exclusive; malformed windows are ignored.
|
||||
"""
|
||||
reference: Final = current_time if current_time is not None else datetime.now(timezone.utc)
|
||||
now: Final = (reference.astimezone(timezone.utc) if reference.tzinfo is not None else reference).time()
|
||||
|
|
@ -308,7 +309,7 @@ def _is_within_off_peak_window(off_peak_hours_utc: str | Sequence[str], current_
|
|||
end = datetime.strptime(end_str.strip(), "%H:%M").replace(tzinfo=timezone.utc).time()
|
||||
except (ValueError, AttributeError):
|
||||
continue
|
||||
if start <= end:
|
||||
if start < end:
|
||||
if start <= now < end:
|
||||
return True
|
||||
elif now >= start or now < end:
|
||||
|
|
|
|||
|
|
@ -431,6 +431,19 @@ def test_is_within_off_peak_window_wraps_midnight():
|
|||
assert _is_within_off_peak_window(window, datetime(2026, 1, 1, 12, 0, tzinfo=timezone.utc)) is False
|
||||
|
||||
|
||||
def test_is_within_off_peak_window_equal_start_and_end_covers_whole_day():
|
||||
"""An equal start and end is the natural way to spell off-peak all day. It used to take the
|
||||
non-wrap branch, where start <= now < end can never hold, so it matched nothing and billed at
|
||||
standard rates around the clock without raising or logging anything."""
|
||||
from datetime import datetime, timezone
|
||||
|
||||
for window in ("00:00-00:00", "10:00-10:00"):
|
||||
for hour in range(24):
|
||||
assert (
|
||||
_is_within_off_peak_window(window, datetime(2026, 1, 1, hour, 0, tzinfo=timezone.utc)) is True
|
||||
), f"{window} should cover {hour:02d}:00"
|
||||
|
||||
|
||||
def test_is_within_off_peak_window_multiple_windows():
|
||||
from datetime import datetime, timezone
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue