- Add base API client and cache manager classes - Implement FMP and YFinance specific clients and cache managers - Add API factory for managing multiple data providers - Add test suite for API configuration and caching - Add logging configuration for API operations
92 lines
2.7 KiB
Python
92 lines
2.7 KiB
Python
#!/usr/bin/env python3
|
|
"""
|
|
Cache System Simulation
|
|
|
|
Demonstrates how the cache system works with API calls and cached data.
|
|
"""
|
|
|
|
import time
|
|
from ETF_Portal.cache_manager import cache_manager
|
|
import logging
|
|
|
|
# Setup logging
|
|
logging.basicConfig(level=logging.INFO)
|
|
logger = logging.getLogger(__name__)
|
|
|
|
def simulate_api_call(source: str, ticker: str, data_type: str) -> dict:
|
|
"""
|
|
Simulate an API call with a delay.
|
|
|
|
Args:
|
|
source: Data source (e.g., 'fmp', 'yahoo')
|
|
ticker: Stock/ETF ticker
|
|
data_type: Type of data (e.g., 'profile', 'historical')
|
|
|
|
Returns:
|
|
Simulated API response data
|
|
"""
|
|
logger.info(f"Making API call to {source} for {ticker} {data_type}")
|
|
time.sleep(1) # Simulate API delay
|
|
return {
|
|
"ticker": ticker,
|
|
"source": source,
|
|
"type": data_type,
|
|
"data": f"Simulated data for {ticker} from {source}",
|
|
"timestamp": time.time()
|
|
}
|
|
|
|
def get_data(source: str, ticker: str, data_type: str) -> dict:
|
|
"""
|
|
Get data either from cache or API.
|
|
|
|
Args:
|
|
source: Data source
|
|
ticker: Stock/ETF ticker
|
|
data_type: Type of data
|
|
|
|
Returns:
|
|
Data from either cache or API
|
|
"""
|
|
# Try to load from cache first
|
|
is_valid, cached_data = cache_manager.load(source, ticker, data_type)
|
|
|
|
if is_valid:
|
|
logger.info(f"Cache HIT: Found valid data for {ticker} in cache")
|
|
return cached_data
|
|
|
|
# If not in cache or expired, fetch from API
|
|
logger.info(f"Cache MISS: Fetching data for {ticker} from API")
|
|
data = simulate_api_call(source, ticker, data_type)
|
|
|
|
# Save to cache
|
|
cache_manager.save(source, ticker, data_type, data)
|
|
return data
|
|
|
|
def run_simulation():
|
|
"""Run a simulation of the cache system."""
|
|
# First request - should be a cache miss
|
|
logger.info("\n=== First Request ===")
|
|
data1 = get_data('fmp', 'SPY', 'profile')
|
|
print(f"Data received: {data1}")
|
|
|
|
# Second request - should be a cache hit
|
|
logger.info("\n=== Second Request ===")
|
|
data2 = get_data('fmp', 'SPY', 'profile')
|
|
print(f"Data received: {data2}")
|
|
|
|
# Request different data - should be a cache miss
|
|
logger.info("\n=== Different Data Request ===")
|
|
data3 = get_data('fmp', 'QQQ', 'profile')
|
|
print(f"Data received: {data3}")
|
|
|
|
# Show cache statistics
|
|
logger.info("\n=== Cache Statistics ===")
|
|
stats = cache_manager.get_stats()
|
|
print(f"Cache hits: {stats['hits']}")
|
|
print(f"Cache misses: {stats['misses']}")
|
|
print(f"Hit rate: {stats['hit_rate']:.2%}")
|
|
print(f"Total cache size: {stats['total_size']} bytes")
|
|
print(f"Number of cache files: {stats['cache_files']}")
|
|
|
|
if __name__ == "__main__":
|
|
run_simulation() |