Tool
v0.2.0
Genius Song Lyrics
Gets the lyrics for a song using Genius. It works fine idk why OpenWebUi keeps rejecting it,
Tool ID
genius_song_lyrics
Downloads
105+

Tool Content
python
"""
title: Genius Song Lyrics
author: MrMilitaryMech
author_url: https://github.com/MrMilitaryMech
version: 0.2.0
"""

import requests
from bs4 import BeautifulSoup


class Tools:
    def __init__(self):
        # Replace the token with your one below this
        self.token = "YOUR GENIUS TOKEN"

    def search_song(self, title: str, artist: str):
        base_url = "https://api.genius.com"
        headers = {"Authorization": f"Bearer {self.token}"}
        search_url = f"{base_url}/search"
        params = {"q": f"{title} {artist}"}
        response = requests.get(search_url, headers=headers, params=params)

        if response.status_code == 200:
            data = response.json()
            hits = data["response"]["hits"]
            for hit in hits:
                if (
                    artist.lower() in hit["result"]["primary_artist"]["name"].lower()
                    and title.lower() in hit["result"]["title"].lower()
                ):
                    return hit["result"]
        return None

    def get_lyrics_url(self, song_id: int):
        base_url = "https://api.genius.com"
        headers = {"Authorization": f"Bearer {self.token}"}
        song_url = f"{base_url}/songs/{song_id}"
        response = requests.get(song_url, headers=headers)

        if response.status_code == 200:
            data = response.json()
            return data["response"]["song"]["url"]
        return None

    def scrape_lyrics(self, lyrics_url: str) -> str:
        response = requests.get(lyrics_url)
        if response.status_code == 200:
            soup = BeautifulSoup(response.text, "html.parser")
            lyrics_div = soup.find_all(
                "div", class_="Lyrics__Container-sc-1ynbvzw-1 kUgSbL"
            )
            if not lyrics_div:
                lyrics_div = soup.find("div", class_="lyrics")

            lyrics = ""
            for div in lyrics_div:
                for br in div.find_all("br"):
                    br.replace_with("\n")
                lyrics += div.get_text() + "\n"

            return lyrics.strip() if lyrics else "Lyrics not found."
        return "Failed to retrieve lyrics."

    def get_song_lyrics(self, title: str, artist: str) -> str:
        """
        Get the lyrics of a given song by title and artist.
        :param title: The title of the song.
        :param artist: The artist of the song.
        :return: The lyrics of the song or an error message.
        """
        if not title or not artist:
            return """The song title or artist has not been defined, so lyrics cannot be determined."""

        try:
            song = self.search_song(title, artist)
            if song:
                song_id = song["id"]
                lyrics_url = self.get_lyrics_url(song_id)
                if lyrics_url:
                    lyrics = self.scrape_lyrics(lyrics_url)
                    return f"Lyrics for '{title}' by '{artist}':\n" + lyrics
                else:
                    return f"Lyrics URL not found for '{title}' by '{artist}'."
            else:
                return f"Lyrics for '{title}' by '{artist}' not found."
        except Exception as e:
            return f"Error fetching lyrics: {str(e)}"