Source code for tools.youtube_search

"""Search YouTube for videos matching a query (no API key required)."""

import json
import logging

from youtube_search import YoutubeSearch

logger = logging.getLogger(__name__)

TOOL_NAME = "search_youtube_videos"
TOOL_DESCRIPTION = (
    "Search YouTube for videos matching a query. Returns titles, "
    "URLs, durations, channels, and thumbnails without requiring "
    "an API key."
)
TOOL_PARAMETERS = {
    "type": "object",
    "properties": {
        "query": {
            "type": "string",
            "description": "The search term to look for on YouTube.",
        },
        "limit": {
            "type": "integer",
            "description": "Maximum number of results (default 5, max 20).",
        },
    },
    "required": ["query"],
}


[docs] async def run(query: str, limit: int = 5, ctx=None) -> str: """Execute this tool and return the result. Args: query (str): Search query or input string. limit (int): Maximum number of items. ctx: Tool execution context providing access to bot internals. Returns: str: Result string. """ if not query or not query.strip(): return json.dumps({"error": "Missing required argument: query cannot be empty."}) limit = max(1, min(limit, 20)) logger.info(f"search_youtube_videos: query='{query}', limit={limit}") try: results = YoutubeSearch(query, max_results=limit).to_dict() if not results: return json.dumps({ "success": True, "query": query, "results": [], "message": "No videos found for this query.", }) videos = [] for video in results: video_id = video.get("id", "") videos.append({ "title": video.get("title", "Unknown"), "id": video_id, "url": f"https://www.youtube.com/watch?v={video_id}" if video_id else video.get("url_suffix", ""), "duration": video.get("duration", "Unknown"), "channel": video.get("channel", "Unknown"), "views": video.get("views", "Unknown"), "published": video.get("publish_time", "Unknown"), "thumbnail": f"https://i.ytimg.com/vi/{video_id}/hqdefault.jpg" if video_id else "", }) logger.info(f"Found {len(videos)} videos for query: '{query}'") return json.dumps({ "success": True, "query": query, "count": len(videos), "results": videos, }, indent=2) except Exception as e: logger.error(f"Error searching YouTube for '{query}': {e}") return json.dumps({"error": f"Failed to search YouTube: {str(e)}"})