#!/usr/bin/env python """ Quick test script for PD API position ratings integration. This script makes REAL API calls to verify the integration works. Run this before committing to ensure API connectivity. Usage: source venv/bin/activate export PYTHONPATH=. python test_pd_api_live.py """ import asyncio import logging from app.services.pd_api_client import pd_api_client from app.services.position_rating_service import position_rating_service # Setup logging logging.basicConfig( level=logging.INFO, format='%(levelname)-8s %(message)s' ) logger = logging.getLogger(__name__) async def test_api_with_known_card(): """Test API with a known PD card ID.""" print("\n" + "="*80) print("TESTING PD API - Position Ratings Integration") print("="*80 + "\n") # Test with known good player ID # Player 8807 has 7 positions (good test case) test_card_ids = [ 8807, # Known player with 7 positions ] for card_id in test_card_ids: print(f"\nšŸ“¦ Testing Card ID: {card_id}") print("-" * 40) try: # Fetch from API ratings = await pd_api_client.get_position_ratings(card_id) if ratings: print(f"āœ“ SUCCESS: Found {len(ratings)} position(s) for card {card_id}\n") # Display ratings table print(f"{'Position':<10} {'Range':<8} {'Error':<8} {'Arm':<8} {'Innings':<10}") print("-" * 50) for rating in ratings: print( f"{rating.position:<10} " f"{rating.range:<8} " f"{rating.error:<8} " f"{rating.arm or 'N/A':<8} " f"{rating.innings:<10}" ) # Test completed successfully - use this card for further tests return card_id, ratings else: print(f"⚠ Card {card_id} has no position ratings") except Exception as e: print(f"āœ— Error fetching card {card_id}: {e}") print("\n⚠ None of the test card IDs returned data") print(" You may need to provide a valid PD card ID") return None, None async def test_caching(card_id): """Test that caching works correctly.""" print("\n" + "="*80) print("TESTING CACHE FUNCTIONALITY") print("="*80 + "\n") # Clear cache first position_rating_service.clear_cache() print(f"šŸ“¦ Testing cache with card {card_id}\n") # First request - should hit API print("1ļøāƒ£ First request (should hit API)...") import time start = time.time() ratings1 = await position_rating_service.get_ratings_for_card(card_id, 'pd') api_time = time.time() - start print(f" Retrieved {len(ratings1)} ratings in {api_time:.3f}s") # Second request - should hit cache print("\n2ļøāƒ£ Second request (should hit cache)...") start = time.time() ratings2 = await position_rating_service.get_ratings_for_card(card_id, 'pd') cache_time = time.time() - start print(f" Retrieved {len(ratings2)} ratings in {cache_time:.3f}s") # Verify cache is faster if cache_time < api_time: speedup = api_time / cache_time if cache_time > 0 else float('inf') print(f"\nāœ“ Cache working! {speedup:.1f}x faster than API") else: print(f"\n⚠ Cache may not be working (cache time >= API time)") print(f"\n API time: {api_time:.4f}s") print(f" Cache time: {cache_time:.4f}s") async def test_specific_position(card_id, position='SS'): """Test getting rating for a specific position.""" print("\n" + "="*80) print(f"TESTING SPECIFIC POSITION LOOKUP ({position})") print("="*80 + "\n") print(f"šŸ“¦ Looking for {position} rating for card {card_id}...") rating = await position_rating_service.get_rating_for_position( card_id=card_id, position=position, league_id='pd' ) if rating: print(f"\nāœ“ Found {position} rating:") print(f" Range: {rating.range}") print(f" Error: {rating.error}") print(f" Arm: {rating.arm}") print(f" Innings: {rating.innings}") else: print(f"\n⚠ Card {card_id} doesn't have {position} rating") async def test_sba_league(): """Test that SBA league skips API calls.""" print("\n" + "="*80) print("TESTING SBA LEAGUE (Should Skip API)") print("="*80 + "\n") print("šŸ“¦ Requesting ratings for SBA league...") ratings = await position_rating_service.get_ratings_for_card( card_id=9999, # Any ID - shouldn't matter league_id='sba' ) if ratings == []: print("āœ“ SBA league correctly returns empty list (no API call)") else: print(f"āœ— Unexpected: SBA returned {len(ratings)} ratings") async def test_full_gamestate_integration(card_id, ratings): """Test full integration with GameState.""" print("\n" + "="*80) print("TESTING FULL GAMESTATE INTEGRATION") print("="*80 + "\n") from uuid import uuid4 from app.models.game_models import GameState, LineupPlayerState, TeamLineupState from app.core.state_manager import state_manager # Create test game game_id = uuid4() print(f"šŸ“¦ Creating test game {game_id}") state = GameState( game_id=game_id, league_id='pd', home_team_id=1, away_team_id=2 ) # Use first position from ratings test_position = ratings[0].position print(f" Using position: {test_position}") # Create lineup player with rating player = LineupPlayerState( lineup_id=1, card_id=card_id, position=test_position, batting_order=1, is_active=True, position_rating=ratings[0] # Attach the rating ) # Create team lineup lineup = TeamLineupState(team_id=1, players=[player]) # Cache in state manager state_manager._states[game_id] = state state_manager.set_lineup(game_id, 1, lineup) print(f"\nšŸ” Testing defender lookup...") # Test GameState.get_defender_for_position() defender = state.get_defender_for_position(test_position, state_manager) if defender and defender.position_rating: print(f"āœ“ Found defender at {test_position}:") print(f" Lineup ID: {defender.lineup_id}") print(f" Card ID: {defender.card_id}") print(f" Range: {defender.position_rating.range}") print(f" Error: {defender.position_rating.error}") print(f"\nāœ“ FULL INTEGRATION SUCCESSFUL!") else: print(f"āœ— Failed to retrieve defender or rating") # Cleanup state_manager.remove_game(game_id) async def main(): """Run all tests.""" print("\nšŸš€ Starting PD API Position Ratings Integration Tests\n") # Test 1: Find a card with position ratings card_id, ratings = await test_api_with_known_card() if not card_id or not ratings: print("\n⚠ Cannot continue tests without valid card data") print(" Please provide a valid PD card ID that has position ratings") return # Test 2: Verify caching works await test_caching(card_id) # Test 3: Get specific position test_position = ratings[0].position # Use first available position await test_specific_position(card_id, test_position) # Test 4: SBA league behavior await test_sba_league() # Test 5: Full GameState integration await test_full_gamestate_integration(card_id, ratings) print("\n" + "="*80) print("āœ“ ALL TESTS COMPLETED") print("="*80 + "\n") print("Summary:") print(f" - API connectivity: āœ“") print(f" - Data retrieval: āœ“") print(f" - Caching: āœ“") print(f" - SBA league: āœ“") print(f" - GameState: āœ“") print(f"\nReady to commit! šŸŽ‰\n") if __name__ == '__main__': asyncio.run(main())