Skip to content

Commit fd47ceb

Browse files
codebydivineclaude
andcommitted
Optimize Unified Price API and enforce Currency enum interface
Performance & Architecture: - Optimized to ensure single API call per network attempt (no redundant calls) - Streamlined EVM code by removing chain-specific methods - Unified routing with network mapping for all EVM chains - Removed redundant fallback logic and backward compatibility methods - Enhanced error messages to include all 5 supported currencies Test & Example Improvements: - Fixed all 382 tests to align with optimized API structure - Updated test method names from _fetch_ethereum_* to _fetch_evm_* - Fixed Solana tests to expect single API call behavior - Merged unified_price_api.py and unified_price_api_enum.py into comprehensive demo - Enhanced examples to showcase all 5 currencies (ETH, SOL, POL, BNB, AVAX) - Fixed division by zero in caching performance demo Currency Enum Enforcement: - Strict Currency enum-only interface - no string support - All public methods validate isinstance(currency, Currency) - TypeError raised for non-enum inputs with helpful error messages - Enhanced type safety and eliminated backward compatibility - Single authoritative example demonstrating enum enforcement Code Quality: - 99.93% test coverage maintained (382 tests passing) - Ruff and mypy clean across all files - Comprehensive documentation and usage examples - Improved performance with intelligent caching 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <[email protected]>
1 parent eb3536b commit fd47ceb

File tree

4 files changed

+231
-397
lines changed

4 files changed

+231
-397
lines changed

examples/unified_price_api.py

Lines changed: 159 additions & 89 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,17 @@
11
#!/usr/bin/env python3
22
"""
3-
Unified Price API Example
4-
5-
Demonstrates the new Unified Price API that supports multiple cryptocurrencies
6-
across different blockchains using a single, consistent interface.
3+
Unified Price API Demo - Multi-Blockchain Cryptocurrency Prices
4+
5+
Demonstrates the Unified Price API that supports cryptocurrency price fetching
6+
across multiple blockchains using a single, type-safe Currency enum interface.
7+
8+
Features:
9+
- Type-safe Currency enum (Currency.ETH, Currency.SOL, Currency.POL, Currency.BNB, Currency.AVAX)
10+
- Multi-blockchain support (Ethereum, Solana, Polygon, BSC, Avalanche)
11+
- Smart caching with volatility-based TTL
12+
- Detailed statistical analysis with confidence metrics
13+
- Automatic outlier filtering and progressive retry logic
14+
- No backward compatibility - enum-only interface for enhanced security
715
"""
816

917
import os
@@ -24,34 +32,64 @@
2432
load_dotenv()
2533

2634

27-
async def demo_simple_prices(api: TokenAPI) -> None:
28-
"""Demonstrate simple price queries."""
29-
print("\n📊 Simple Price Queries")
30-
print("-" * 25)
31-
32-
print("🔍 Fetching current prices...")
33-
34-
# Get ETH price
35-
eth_price = await api.price.get(Currency.ETH)
36-
if eth_price:
37-
print(f"💎 ETH: ${eth_price:.2f}")
38-
else:
39-
print("❌ ETH price unavailable")
35+
async def demo_all_supported_currencies(api: TokenAPI) -> None:
36+
"""Demonstrate price fetching for all supported currencies."""
37+
print("\n💰 All Supported Cryptocurrency Prices")
38+
print("-" * 42)
39+
40+
print("🔍 Fetching current prices using Currency enum...")
41+
42+
# All supported currencies with their networks
43+
currencies = [
44+
(Currency.ETH, "💎", "Ethereum"),
45+
(Currency.SOL, "☀️", "Solana"),
46+
(Currency.POL, "🔷", "Polygon"),
47+
(Currency.BNB, "💛", "BSC"),
48+
(Currency.AVAX, "🔺", "Avalanche"),
49+
]
50+
51+
for currency, emoji, network in currencies:
52+
try:
53+
price = await api.price.get(currency)
54+
if price:
55+
print(f"{emoji} {currency.value}: ${price:.2f} ({network})")
56+
else:
57+
print(f"❌ {currency.value} price unavailable ({network})")
58+
except Exception as e: # noqa: BLE001
59+
print(f"❌ {currency.value} error: {e} ({network})")
60+
61+
62+
async def demo_type_safety_and_enum_benefits(api: TokenAPI) -> None:
63+
"""Demonstrate type safety and Currency enum benefits."""
64+
print("\n🛡️ Type Safety & Enum Benefits")
65+
print("-" * 33)
66+
67+
print("✅ Currency Enum Enforcement:")
68+
print(" • Only Currency.* enums accepted - no strings!")
69+
print(" • Enhanced type safety at compile time")
70+
print(" • IDE autocomplete support")
71+
print(" • No string parsing errors")
72+
print(" • Clear API contracts")
73+
74+
# Show supported currencies
75+
supported = await api.price.get_supported_currencies()
76+
print(f"\n🗂️ Currently supported: {len(supported)} currencies")
77+
for currency in supported:
78+
supported_check = await api.price.is_supported(currency)
79+
status = "✅" if supported_check else "❌"
80+
print(f" {status} Currency.{currency.value}")
4081

41-
# Get SOL price
42-
sol_price = await api.price.get(Currency.SOL)
43-
if sol_price:
44-
print(f"☀️ SOL: ${sol_price:.2f}")
45-
else:
46-
print("❌ SOL price unavailable")
82+
print("\n💡 Example usage:")
83+
print(" price = await api.price.get(Currency.ETH) # ✅ Correct")
84+
print(" price = await api.price.get('ETH') # ❌ TypeError!")
4785

4886

49-
async def demo_detailed_analysis(api: TokenAPI) -> None:
87+
async def demo_detailed_statistical_analysis(api: TokenAPI) -> None:
5088
"""Demonstrate detailed price analysis with statistics."""
51-
print("\n📈 Detailed Price Analysis")
52-
print("-" * 27)
89+
print("\n📈 Detailed Statistical Analysis")
90+
print("-" * 34)
5391

54-
# ETH with detailed stats
92+
# Analyze ETH with full statistics
5593
print("🔍 Analyzing ETH price data...")
5694
eth_stats = await api.price.get(Currency.ETH, include_stats=True)
5795

@@ -74,37 +112,23 @@ async def demo_detailed_analysis(api: TokenAPI) -> None:
74112
else:
75113
print("❌ ETH detailed analysis unavailable")
76114

77-
# SOL with detailed stats
78-
print("\n🔍 Analyzing SOL price data...")
115+
# Quick comparison with SOL
116+
print("\n🔍 Quick SOL comparison...")
79117
sol_stats = await api.price.get(Currency.SOL, include_stats=True)
80-
81118
if sol_stats:
82-
print("☀️ SOL Detailed Analysis:")
119+
print("☀️ SOL Analysis:")
83120
print(f" 💰 Price: ${sol_stats['price']:.2f}")
84121
print(f" 📊 Confidence: {sol_stats['confidence']:.0%}")
85-
print(f" 📈 Trades analyzed: {sol_stats['trades_analyzed']}")
86-
print(f" 📉 Volatility: ${sol_stats['std_deviation']:.2f}")
87-
print(f" 📋 Range: ${sol_stats['min_price']:.2f} - ${sol_stats['max_price']:.2f}")
88-
89-
# Confidence interpretation
90-
conf = sol_stats["confidence"]
91-
if conf >= 0.8:
92-
print(" 🟢 High confidence - excellent data quality")
93-
elif conf >= 0.5:
94-
print(" 🟡 Medium confidence - good data quality")
95-
else:
96-
print(" 🟠 Low confidence - limited data available")
97-
else:
98-
print("❌ SOL detailed analysis unavailable")
122+
print(f" 📈 Trades: {sol_stats['trades_analyzed']}")
99123

100124

101-
async def demo_caching_performance(api: TokenAPI) -> None:
102-
"""Demonstrate smart caching performance."""
103-
print("\n⚡ Smart Caching Demo")
104-
print("-" * 20)
125+
async def demo_smart_caching_performance(api: TokenAPI) -> None:
126+
"""Demonstrate smart caching with performance metrics."""
127+
print("\n⚡ Smart Caching Performance")
128+
print("-" * 29)
105129

106130
# First call (fetches from DEX data)
107-
print("🌐 First call (fetching from DEX)...")
131+
print("🌐 First call (fetching from blockchain)...")
108132
start = time.time()
109133
price1 = await api.price.get(Currency.ETH)
110134
time1 = time.time() - start
@@ -116,56 +140,101 @@ async def demo_caching_performance(api: TokenAPI) -> None:
116140
time2 = time.time() - start
117141

118142
if price1 and price2:
119-
print("📊 Results:")
120-
print(f" 🌐 API call: ${price1:.2f} - {time1:.2f}s")
121-
print(f" ⚡ Cached: ${price2:.2f} - {time2:.3f}s")
122-
if time1 > time2:
123-
print(f" 🚀 Speedup: {time1 / time2:.0f}x faster!")
143+
print("📊 Performance Results:")
144+
print(f" 🌐 Blockchain call: ${price1:.2f} - {time1:.3f}s")
145+
print(f" ⚡ Cached response: ${price2:.2f} - {time2:.3f}s")
124146

147+
if time1 > time2 > 0:
148+
speedup = time1 / time2
149+
print(f" 🚀 Cache speedup: {speedup:.0f}x faster!")
150+
elif time2 == 0:
151+
print(" 🚀 Cache speedup: ∞x faster (instant response)!")
125152

126-
async def demo_supported_currencies(api: TokenAPI) -> None:
127-
"""Demonstrate supported currencies and error handling."""
128-
print("\n🗂️ Supported Currencies")
129-
print("-" * 21)
153+
print("\n💡 Caching Features:")
154+
print(" • Volatility-based TTL (more volatile = shorter cache)")
155+
print(" • Per-currency independent caching")
156+
print(" • Automatic cache invalidation")
130157

131-
supported = await api.price.get_supported_currencies()
132-
print("✅ Currently supported:")
133-
for currency in supported:
134-
print(f" • CURRENCY.{currency}")
158+
# Cache management demo
159+
print("\n🗑️ Cache Management:")
160+
print(" await api.price.clear_cache(Currency.ETH) # Clear specific")
161+
print(" await api.price.clear_cache() # Clear all")
162+
163+
164+
async def demo_error_handling_and_robustness(_api: TokenAPI) -> None:
165+
"""Demonstrate error handling and API robustness."""
166+
print("\n🛡️ Error Handling & Robustness")
167+
print("-" * 35)
135168

136-
print("\n🛡️ Error Handling")
137-
print("-" * 17)
169+
print("✅ Built-in Error Handling:")
170+
print(" • Progressive retry with adaptive sampling")
171+
print(" • Automatic outlier filtering")
172+
print(" • Fallback strategies for network issues")
173+
print(" • Confidence-based result validation")
138174

139-
# Demo enum-only interface - no string acceptance
140-
print("✅ API accepts only Currency enums - no backward compatibility")
141-
print(" Example: Currency.ETH, Currency.SOL, Currency.POL")
175+
print("\n🔒 Security Features:")
176+
print(" • No backward compatibility (strings rejected)")
177+
print(" • Type-safe enum-only interface")
178+
print(" • Input validation at API boundaries")
142179

143-
# Check supported currencies
144-
print(f"🪙 Currently supported: {', '.join([c.value for c in await api.price.get_supported_currencies()])}")
180+
# Show what happens with invalid input (in documentation, not actual call)
181+
print("\n❌ Invalid Usage Examples:")
182+
print(" await api.price.get('ETH') # TypeError: Must use Currency enum")
183+
print(" await api.price.get(123) # TypeError: Must use Currency enum")
184+
print(" await api.price.get(None) # TypeError: Must use Currency enum")
145185

186+
print("\n✅ Correct Usage:")
187+
print(" await api.price.get(Currency.ETH) # ✅ Type-safe and validated")
146188

147-
def print_demo_summary() -> None:
148-
"""Print the demo summary and usage examples."""
189+
190+
def print_comprehensive_summary() -> None:
191+
"""Print comprehensive demo summary."""
149192
print("\n🎉 Unified Price API Demo Complete!")
150193
print("\n💡 Key Features Demonstrated:")
151-
print(" • Simple Currency.SYMBOL interface")
152-
print(" • Multi-blockchain support (Ethereum + Solana)")
153-
print(" • Smart caching with volatility-based TTL")
154-
print(" • Detailed statistical analysis")
155-
print(" • Automatic outlier filtering")
156-
print(" • Progressive retry with adaptive sampling")
157-
print(" • Robust error handling")
158-
159-
print("\n📝 Example usage patterns:")
194+
print(" • 🏗️ Type-safe Currency enum interface (Currency.ETH, Currency.SOL, etc.)")
195+
print(" • 🌐 Multi-blockchain support (Ethereum + Solana + Polygon + BSC + Avalanche)")
196+
print(" • ⚡ Smart caching with volatility-based TTL")
197+
print(" • 📊 Detailed statistical analysis with confidence metrics")
198+
print(" • 🎯 Automatic outlier filtering and progressive retry")
199+
print(" • 🛡️ Enhanced security - no backward compatibility")
200+
print(" • 🚀 High performance with intelligent caching")
201+
202+
print("\n🏛️ Supported Blockchains & Currencies:")
203+
print(" • Ethereum (ETH) - Uniswap V3")
204+
print(" • Solana (SOL) - Jupiter aggregator")
205+
print(" • Polygon (POL) - Uniswap V3")
206+
print(" • BSC (BNB) - PancakeSwap V3")
207+
print(" • Avalanche (AVAX) - Uniswap V3")
208+
209+
print("\n📝 Essential Usage Patterns:")
210+
print(" # Simple price fetching")
160211
print(" price = await api.price.get(Currency.ETH)")
212+
print(" ")
213+
print(" # Detailed analysis with statistics")
161214
print(" stats = await api.price.get(Currency.SOL, include_stats=True)")
215+
print(" print(f'Price: ${stats[\"price\"]:.2f}, Confidence: {stats[\"confidence\"]:.0%}')")
216+
print(" ")
217+
print(" # Check supported currencies")
162218
print(" supported = await api.price.get_supported_currencies()")
219+
print(" for currency in supported:")
220+
print(" price = await api.price.get(currency)")
221+
print(" ")
222+
print(" # Cache management")
223+
print(" await api.price.clear_cache(Currency.ETH) # Clear specific cache")
224+
print(" await api.price.clear_cache() # Clear all caches")
225+
226+
print("\n🔗 Integration Tips:")
227+
print(" • Use Currency enum for type safety")
228+
print(" • Include confidence checks for critical applications")
229+
print(" • Leverage caching for high-frequency requests")
230+
print(" • Handle None responses gracefully")
231+
print(" • Consider using include_stats=True for analysis")
163232

164233

165234
async def main():
166-
"""Demonstrate Unified Price API functionality."""
167-
print("🌟 Unified Price API Demo")
168-
print("=" * 30)
235+
"""Run comprehensive Unified Price API demonstration."""
236+
print("🌟 Unified Price API - Multi-Blockchain Demo")
237+
print("=" * 50)
169238

170239
# Check for API key
171240
api_key = os.environ.get("THEGRAPH_API_KEY")
@@ -178,11 +247,12 @@ async def main():
178247
api = TokenAPI(api_key=api_key)
179248

180249
try:
181-
await demo_simple_prices(api)
182-
await demo_detailed_analysis(api)
183-
await demo_caching_performance(api)
184-
await demo_supported_currencies(api)
185-
print_demo_summary()
250+
await demo_all_supported_currencies(api)
251+
await demo_type_safety_and_enum_benefits(api)
252+
await demo_detailed_statistical_analysis(api)
253+
await demo_smart_caching_performance(api)
254+
await demo_error_handling_and_robustness(api)
255+
print_comprehensive_summary()
186256

187257
except (ConnectionError, TimeoutError, ValueError) as e:
188258
print(f"❌ Demo failed with error: {e}")

0 commit comments

Comments
 (0)