Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 17 additions & 2 deletions app/currency.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,17 @@
FLOATRATES_URL = "https://www.floatrates.com/daily/eur.json"
ERAPI_URL = "https://open.er-api.com/v6/latest/EUR"


def ensure_timezone_aware(dt, default_tz=timezone.utc):
Copy link

Copilot AI Oct 6, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The function parameter dt should be documented with its expected type in the docstring for better API clarity.

Copilot uses AI. Check for mistakes.
"""
Ensure a datetime object is timezone-aware.
If naive, assume it's in the default timezone (UTC by default).
"""
Copy link

Copilot AI Oct 6, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Missing input validation for the dt parameter. The function should handle cases where dt is None or not a datetime object to prevent AttributeError.

Suggested change
"""
"""
if dt is None:
raise ValueError("dt cannot be None")
if not isinstance(dt, datetime):
raise TypeError(f"dt must be a datetime object, got {type(dt).__name__}")

Copilot uses AI. Check for mistakes.
if dt.tzinfo is None:
return dt.replace(tzinfo=default_tz)
return dt


class CurrencyConverter:
"""Currency converter with multi-provider fallback and provider-specific caching."""

Expand Down Expand Up @@ -60,7 +71,9 @@ def get_exchange_rates(self, base_currency: str = 'EUR', force_refresh: bool = F
if not force_refresh and primary_provider:
record = ExchangeRate.query.filter_by(date=date.today(), base_currency=base_currency, provider=primary_provider).first()
if record:
age_min = (datetime.now(timezone.utc) - record.created_at).total_seconds() / 60.0
# Handle timezone compatibility - assume database datetime is UTC if naive
record_time = ensure_timezone_aware(record.created_at)
age_min = (datetime.now(timezone.utc) - record_time).total_seconds() / 60.0
if age_min <= refresh_minutes:
try:
self.last_provider = primary_provider
Expand All @@ -79,7 +92,9 @@ def get_exchange_rates(self, base_currency: str = 'EUR', force_refresh: bool = F
if not force_refresh:
cached = ExchangeRate.query.filter_by(date=date.today(), base_currency=base_currency, provider=provider).first()
if cached:
age_min = (datetime.now(timezone.utc) - cached.created_at).total_seconds() / 60.0
# Handle timezone compatibility - assume database datetime is UTC if naive
cached_time = ensure_timezone_aware(cached.created_at)
age_min = (datetime.now(timezone.utc) - cached_time).total_seconds() / 60.0
if age_min <= refresh_minutes:
try:
self.last_provider = provider
Expand Down
Loading