Skip to main content
Glama
fallback_youtube_service.py6.34 kB
""" Fallback YouTube service that combines multiple implementations. """ from typing import List, Dict, Any, Optional, Tuple from infrastructure.logging import logger from infrastructure.cache import cache from api.models import Resource from services.youtube.youtube_service import YouTubeService class FallbackYouTubeService(YouTubeService): """ Fallback YouTube service that combines multiple implementations. Tries each implementation in order until one succeeds. """ def __init__(self, services: List[Tuple[YouTubeService, float]], cache_ttl: int = 86400): """ Initialize the fallback YouTube service. Args: services: List of (service, weight) tuples cache_ttl: Cache TTL in seconds (default: 1 day) """ self.services = services self.cache_ttl = cache_ttl self.logger = logger.get_logger("youtube.fallback") service_names = [service[0].__class__.__name__ for service in services] self.logger.info(f"Initialized FallbackYouTubeService with services: {', '.join(service_names)}") async def search_videos(self, query: str, max_results: int = 5, language: str = "en") -> List[Dict[str, Any]]: """ Search for YouTube videos using multiple implementations with fallback. Args: query: Search query max_results: Maximum number of results to return language: Language code (e.g., 'en', 'pt') Returns: List of dictionaries with video information """ # Check cache first cache_key = f"youtube:fallback:search:{query}_{max_results}_{language}" cached_result = cache.get(cache_key) if cached_result: self.logger.debug(f"Using cached fallback YouTube search results for '{query}'") return cached_result # Try each service in order for service, _ in self.services: try: self.logger.debug(f"Trying YouTube service: {service.__class__.__name__}") results = await service.search_videos(query, max_results, language) if results: self.logger.info(f"YouTube search successful with {service.__class__.__name__} ({len(results)} results)") # Cache the results cache.setex(cache_key, self.cache_ttl, results) return results else: self.logger.warning(f"No results from {service.__class__.__name__}, trying next service") except Exception as e: self.logger.error(f"Error with YouTube service {service.__class__.__name__}: {str(e)}") # If all services fail, return empty list self.logger.error(f"All YouTube services failed for query: {query}") return [] async def get_video_details(self, video_id: str) -> Optional[Dict[str, Any]]: """ Get details for a specific video using multiple implementations with fallback. Args: video_id: YouTube video ID Returns: Dictionary with video details or None if not found """ # Check cache first cache_key = f"youtube:fallback:video:{video_id}" cached_result = cache.get(cache_key) if cached_result: self.logger.debug(f"Using cached fallback YouTube video details for '{video_id}'") return cached_result # Try each service in order for service, _ in self.services: try: self.logger.debug(f"Trying YouTube service for video details: {service.__class__.__name__}") result = await service.get_video_details(video_id) if result: self.logger.info(f"YouTube video details successful with {service.__class__.__name__}") # Cache the result cache.setex(cache_key, self.cache_ttl, result) return result else: self.logger.warning(f"No video details from {service.__class__.__name__}, trying next service") except Exception as e: self.logger.error(f"Error with YouTube service {service.__class__.__name__}: {str(e)}") # If all services fail, return None self.logger.error(f"All YouTube services failed for video: {video_id}") return None async def search_videos_for_topic(self, topic: str, subtopic: str = None, max_results: int = 3, language: str = "en") -> List[Resource]: """ Search for videos related to a topic and convert to Resource objects. Args: topic: Main topic subtopic: Optional subtopic for more specific results max_results: Maximum number of results to return language: Language code (e.g., 'en', 'pt') Returns: List of Resource objects """ # Check cache first cache_key = f"youtube:fallback:topic:{topic}_{subtopic}_{max_results}_{language}" cached_result = cache.get(cache_key) if cached_result: self.logger.debug(f"Using cached fallback YouTube topic results for '{topic}'") return cached_result # Try each service in order for service, _ in self.services: try: self.logger.debug(f"Trying YouTube service for topic: {service.__class__.__name__}") results = await service.search_videos_for_topic(topic, subtopic, max_results, language) if results: self.logger.info(f"YouTube topic search successful with {service.__class__.__name__} ({len(results)} results)") # Cache the results cache.setex(cache_key, self.cache_ttl, results) return results else: self.logger.warning(f"No topic results from {service.__class__.__name__}, trying next service") except Exception as e: self.logger.error(f"Error with YouTube service {service.__class__.__name__}: {str(e)}") # If all services fail, return empty list self.logger.error(f"All YouTube services failed for topic: {topic}") return []

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/cabrit0/mcp_server_reuneMacacada'

If you have feedback or need assistance with the MCP directory API, please join our Discord server