""" API client utilities for Spark POC testing Simulates Apify/Clockworks integration and HTTP requests """ import time import json from datetime import datetime def test_http_request(): """Test basic HTTP request capability (simulated)""" try: # In real implementation, would make actual HTTP request # For now, simulate the test # Simulate request delay time.sleep(0.1) return { 'status': '✅ HTTP request successful (simulated)', 'response_time': 0.1, 'status_code': 200 } except Exception as e: return { 'status': f'❌ HTTP request failed: {str(e)}', 'response_time': None, 'status_code': None } def simulate_apify_call(track_id, max_results=10): """Simulate Apify Clockworks TikTok scraper call""" try: # Simulate API call delay time.sleep(0.2) # Mock response data structure mock_data = { 'status': 'success', 'track_id': track_id, 'total_videos': 145, 'videos': [ { 'video_id': f'v_{track_id}_001', 'creator': 'tiktoker_1', 'creator_profile_url': 'https://tiktok.com/@tiktoker_1', 'views': 25000, 'likes': 3500, 'shares': 250, 'hearts': 3500, 'url': f'https://tiktok.com/video/{track_id}_001', 'scraped_at': datetime.now().isoformat() }, { 'video_id': f'v_{track_id}_002', 'creator': 'tiktoker_2', 'creator_profile_url': 'https://tiktok.com/@tiktoker_2', 'views': 18000, 'likes': 2200, 'shares': 180, 'hearts': 2200, 'url': f'https://tiktok.com/video/{track_id}_002', 'scraped_at': datetime.now().isoformat() } ], 'scraped_at': datetime.now().isoformat(), 'api_credits_used': 5 } return { 'success': True, 'message': '✅ Apify simulation successful', 'mock_data': mock_data, 'request_time': 0.2 } except Exception as e: return { 'success': False, 'message': f'❌ Apify simulation failed: {str(e)}', 'mock_data': None, 'request_time': None } def validate_response(response_data): """Validate API response data structure""" try: if not response_data: return "❌ Empty response" required_fields = ['status', 'track_id', 'total_videos', 'videos'] missing_fields = [field for field in required_fields if field not in response_data] if missing_fields: return f"❌ Missing required fields: {missing_fields}" # Validate video data structure if not response_data['videos']: return "⚠️ No video data found" video_fields = ['video_id', 'creator', 'views', 'likes', 'url'] for i, video in enumerate(response_data['videos'][:3]): # Check first 3 missing_video_fields = [field for field in video_fields if field not in video] if missing_video_fields: return f"❌ Video {i} missing fields: {missing_video_fields}" return f"✅ Response validation passed - {len(response_data['videos'])} videos" except Exception as e: return f"❌ Validation error: {str(e)}" def format_apify_request(tiktok_music_url, max_results=100): """Format request payload for Apify Clockworks scraper""" return { "musics": [tiktok_music_url], "resultsPerPage": max_results, "shouldDownloadCovers": False, "shouldDownloadMusicCovers": False, "shouldDownloadSlideshowImages": False, "shouldDownloadSubtitles": False, "shouldDownloadVideos": False } def handle_api_error(error, context="API call"): """Handle and categorize API errors""" error_str = str(error).lower() if 'timeout' in error_str: return { 'category': 'timeout', 'message': f'⏱️ {context} timed out - try again later', 'retry_recommended': True } elif 'rate limit' in error_str or '429' in error_str: return { 'category': 'rate_limit', 'message': f'🚦 Rate limit exceeded for {context}', 'retry_recommended': True } elif 'network' in error_str or 'connection' in error_str: return { 'category': 'network', 'message': f'🌐 Network error during {context}', 'retry_recommended': True } elif 'authentication' in error_str or '401' in error_str: return { 'category': 'auth', 'message': f'🔑 Authentication failed for {context}', 'retry_recommended': False } else: return { 'category': 'unknown', 'message': f'❓ Unknown error in {context}: {error}', 'retry_recommended': False } def get_api_config(): """Get API configuration (simulated)""" return { 'apify_token': 'your-apify-token-here', 'clockworks_actor': 'clockworks/tiktok-sound-scraper', 'base_url': 'https://api.apify.com/v2', 'timeout': 300, # 5 minutes for TikTok scraping 'max_retries': 3, 'retry_delay': 10 # seconds } def estimate_api_cost(num_songs, avg_videos_per_song=100): """Estimate Apify API costs (simulated)""" # These are example calculations - actual costs depend on Apify pricing cost_per_1k_results = 0.10 # Example cost total_results = num_songs * avg_videos_per_song estimated_cost = (total_results / 1000) * cost_per_1k_results return { 'num_songs': num_songs, 'estimated_total_results': total_results, 'estimated_cost_usd': round(estimated_cost, 2), 'cost_breakdown': f'${cost_per_1k_results} per 1K results' }