mgbam commited on
Commit
bb6c552
Β·
verified Β·
1 Parent(s): fa59443

Update app/price_fetcher.py

Browse files
Files changed (1) hide show
  1. app/price_fetcher.py +15 -45
app/price_fetcher.py CHANGED
@@ -10,7 +10,12 @@ Features:
10
  """
11
  import asyncio
12
  import logging
13
- from typing import Callable, TypedDict, Awaitable
 
 
 
 
 
14
 
15
  import httpx
16
 
@@ -46,7 +51,7 @@ class PriceFetcher:
46
  """
47
  self.client = client
48
  self.coins = coins
49
- self._prices: dict[str, float | str] = {coin: "--" for coin in coins}
50
  self._lock = asyncio.Lock() # Lock to prevent race conditions on the cache
51
  self.sources: list[PriceSource] = self._configure_sources()
52
 
@@ -92,8 +97,13 @@ class PriceFetcher:
92
  except (KeyError, TypeError, ValueError) as e:
93
  logging.error("❌ [CoinCap] Failed to parse response: %s", e)
94
  return {}
95
-
96
- def get_current_prices(self) -> dict[str, float | str]:
 
 
 
 
 
97
  """Returns a copy of the current price cache. Thread-safe read."""
98
  return self._prices.copy()
99
 
@@ -132,44 +142,4 @@ class PriceFetcher:
132
  # Brief pause before trying the next API source
133
  await asyncio.sleep(1)
134
 
135
- logging.error("❌ All price APIs failed. Retaining stale prices.")
136
-
137
-
138
- async def run_price_updates_periodically(fetcher: PriceFetcher, interval_seconds: int):
139
- """A background task runner to keep prices updated."""
140
- logging.info("πŸš€ Starting periodic price updates...")
141
- while True:
142
- await fetcher.update_prices_async()
143
- await asyncio.sleep(interval_seconds)
144
-
145
-
146
- # --- Example Usage ---
147
- if __name__ == "__main__":
148
- async def main():
149
- """Demonstrates how to use the PriceFetcher."""
150
- target_coins = ["bitcoin", "ethereum", "dogecoin"]
151
-
152
- async with httpx.AsyncClient() as client:
153
- price_fetcher = PriceFetcher(client, coins=target_coins)
154
-
155
- # Run the price updates in the background
156
- update_task = asyncio.create_task(
157
- run_price_updates_periodically(price_fetcher, interval_seconds=10)
158
- )
159
-
160
- # In a real app, the server would be running. Here, we just print prices.
161
- for i in range(5):
162
- await asyncio.sleep(11)
163
- current_prices = price_fetcher.get_current_prices()
164
- print(f"--- Main App Reading Cache ({i+1}/5) ---")
165
- for coin, price in current_prices.items():
166
- print(f" {coin.capitalize()}: ${price}")
167
-
168
- # Cleanly shut down the background task
169
- update_task.cancel()
170
- try:
171
- await update_task
172
- except asyncio.CancelledError:
173
- logging.info("Shutdown complete.")
174
-
175
- asyncio.run(main())
 
10
  """
11
  import asyncio
12
  import logging
13
+ # ====================================================================
14
+ # FIX APPLIED HERE (1 of 2)
15
+ # ====================================================================
16
+ # Import Union for Python 3.9 compatibility, and other necessary types.
17
+ from typing import Callable, TypedDict, Awaitable, Union
18
+ # ====================================================================
19
 
20
  import httpx
21
 
 
51
  """
52
  self.client = client
53
  self.coins = coins
54
+ self._prices: dict[str, Union[float, str]] = {coin: "--" for coin in coins}
55
  self._lock = asyncio.Lock() # Lock to prevent race conditions on the cache
56
  self.sources: list[PriceSource] = self._configure_sources()
57
 
 
97
  except (KeyError, TypeError, ValueError) as e:
98
  logging.error("❌ [CoinCap] Failed to parse response: %s", e)
99
  return {}
100
+
101
+ # ====================================================================
102
+ # FIX APPLIED HERE (2 of 2)
103
+ # ====================================================================
104
+ # Changed the type hint from `float | str` to `Union[float, str]`.
105
+ def get_current_prices(self) -> dict[str, Union[float, str]]:
106
+ # ====================================================================
107
  """Returns a copy of the current price cache. Thread-safe read."""
108
  return self._prices.copy()
109
 
 
142
  # Brief pause before trying the next API source
143
  await asyncio.sleep(1)
144
 
145
+ logging.error("❌ All price APIs failed. Retaining stale prices.")