Download song lyrics and metadata from Genius.com 🎶🎤

Overview

LyricsGenius: a Python client for the Genius.com API

Build Status Documentation Status PyPI version Python version

lyricsgenius provides a simple interface to the song, artist, and lyrics data stored on Genius.com.

The full documentation for lyricsgenius is available online at Read the Docs.

Setup

Before using this package you'll need to sign up for a (free) account that authorizes access to the Genius API. The Genius account provides a access_token that is required by the package. See the Usage section below for examples.

Installation

lyricsgenius requires Python 3.

Use pip to install the package from PyPI:

pip install lyricsgenius

Or, install the latest version of the package from GitHub:

pip install git+https://github.com/johnwmillr/LyricsGenius.git

Usage

Import the package and initiate Genius:

import lyricsgenius
genius = lyricsgenius.Genius(token)

If you don't pass a token to the Genius class, lyricsgenus will look for an environment variable called GENIUS_ACCESS_TOKEN and attempt to use that for authentication.

genius = Genius()

Search for songs by a given artist:

artist = genius.search_artist("Andy Shauf", max_songs=3, sort="title")
print(artist.songs)

By default, the search_artist() only returns songs where the given artist is the primary artist. However, there may be instances where it is desirable to get all of the songs that the artist appears on. You can do this by setting the include_features argument to True.

artist = genius.search_artist("Andy Shauf", max_songs=3, sort="title", include_features=True)
print(artist.songs)

Search for a single song by the same artist:

song = artist.song("To You")
# or:
# song = genius.search_song("To You", artist.name)
print(song.lyrics)

Add the song to the artist object:

artist.add_song(song)
# the Artist object also accepts song names:
# artist.add_song("To You")

Save the artist's songs to a JSON file:

artist.save_lyrics()

Searching for an album and saving it:

album = genius.search_album("The Party", "Andy Shauf")
album.save_lyrics()

There are various options configurable as parameters within the Genius class:

genius.verbose = False # Turn off status messages
genius.remove_section_headers = True # Remove section headers (e.g. [Chorus]) from lyrics when searching
genius.skip_non_songs = False # Include hits thought to be non-songs (e.g. track lists)
genius.excluded_terms = ["(Remix)", "(Live)"] # Exclude songs with these words in their title

You can also call the package from the command line:

export GENIUS_ACCESS_TOKEN="my_access_token_here"
python3 -m lyricsgenius --help

Search for and save lyrics to a given song and album:

python3 -m lyricsgenius song "Begin Again" "Andy Shauf" --save
python3 -m lyricsgenius album "The Party" "Andy Shauf" --save

Search for five songs by 'The Beatles' and save the lyrics:

python3 -m lyricsgenius artist "The Beatles" --max-songs 5 --save

Example projects

Contributing

Please contribute! If you want to fix a bug, suggest improvements, or add new features to the project, just open an issue or send me a pull request.

Comments
  • Fixed issue with printing unicode

    Fixed issue with printing unicode

    Whenever there were unicode characters that needed to be printed, an error would be produced. I encoded the print statements and it resolved the issue.

    opened by DarrelDonald 16
  • Added get_referents() and get_song_annotations() functions

    Added get_referents() and get_song_annotations() functions

    get_song_annotations() can be used for getting all song's annotations from a song id. It returns a list of tuple : (fragment, list_of_annotations). Each fragment correspond to a highlighted part of the song, where people can write annotations. Resolve #100

    enhancement 
    opened by ludehon 14
  • Error message

    Error message

    Hi, I get an error message while using your code:

    import lyricsgenius as genius api = genius.Genius('----my api code ---') artist = api.search_artist('Andy Shauf', max_songs=3)

    Error message:

    Traceback (most recent call last): File "C:/Users/Chris/AppData/Local/Programs/Python/Python37-32/top2000/181208 top2000.py", line 3, in artist = api.search_artist('Andy Shauf', max_songs=3) File "C:\Users\Chris\AppData\Local\Programs\Python\Python37-32\lib\site-packages\lyricsgenius\api.py", line 283, in search_artist found_name = artist_info['artist']['name'] TypeError: 'NoneType' object is not subscriptable

    Can you help me with this? Many thanks!

    opened by Chris31070 14
  • Version 3

    Version 3

    Version 2.0.2 that was just released on PyPi introduces new features and more importantly breaking changes. If we were to follow Semantic Versioning, 2.0.2 probably should've been 3.0. Supposing we merge #156, #158, #159, and another one I have coming where Genius no longer needs a token (I should've actually implemented that in #160), what version do you think it should be? We could go for 2.1.0 which is against Semantic Versioning, or 3.0? I'd love to hear your thoughts on this.

    opened by allerter 13
  • Returned songs have NoneType Lyrics. No Lyrics are returned

    Returned songs have NoneType Lyrics. No Lyrics are returned

    Hi there! I would like to use this library to get lyrics of a bunch of songs, and perform some NLP experiments. I have successfully created an API client through genius.com, and got the credentials along with the client access token. However, when I try to get some Rihanna's songs' lyrics, I only get NoneType Objects. Below is the super simple code I have used to get the lyrics:

    import lyricsgenius
    
    genius = lyricsgenius.Genius('xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx', skip_non_songs=True, excluded_terms=["(Remix)", "(Live)"], remove_section_headers=True)
    
    artist = genius.search_artist("Rihanna", max_songs=10, sort="popularity")
    for song in artist.songs:
         print(song.lyrics)
    

    And the printed result is:

    Searching for songs by Rihanna...
    
    Song 1: "Work"
    Song 2: "Needed Me"
    Song 3: "Love on the Brain"
    Song 4: "Stay"
    Song 5: "Kiss it Better"
    Song 6: "Sex with Me"
    Song 7: "Bitch Better Have My Money"
    "Bad (Remix)" is not valid. Skipping.
    Song 8: "Consideration"
    Song 9: "Diamonds"
    Song 10: "Desperado"
    
    Reached user-specified song limit (10).
    Done. Found 10 songs.
    
    None
    None
    None
    None
    None
    None
    None
    None
    None
    None
    

    All the 10 collected songs, have a field called 'lyrics' but all of them are empty. More specifically is of type 'NoneType object of builtins module'. What am I doing wrong? Thanks in advance!

    bug 
    opened by samlidippos 13
  • Timeouts at seemingly random moments

    Timeouts at seemingly random moments

    I'm trying to download a huge number of lyrics for a university project. I have files that represent a genre which contain 50 artists I want to download all lyrics from.

    So I wrote a python script that scans the folder and reads the lists one by one, trying to download the lyrics for every artist in these lists.

    Sometimes the following happens:

    Timeout raised and caught: HTTPSConnectionPool(host='api.genius.com', port=443): Read timed out. (read timeout=5) Traceback (most recent call last): File "lyricsapi.py", line 54, in artist = api.search_artist(a.strip(), max_songs=max_songs, sort="title") File "/home/duke/anaconda3/envs/dynamusic/lib/python3.7/site-packages/lyricsgenius/api.py", line 356, in search_artist song = Song(info, lyrics) File "/home/duke/anaconda3/envs/dynamusic/lib/python3.7/site-packages/lyricsgenius/song.py", line 26, in init self._body = json_dict['song'] if 'song' in json_dict else json_dict TypeError: argument of type 'NoneType' is not iterable

    This error happens pretty randomly, sometimes after 50 texts, sometimes after 600. Earlier today it happened after downloading 113 texts by Eminem, but in the next try it managed to download all 490 of his songs, just to fail after a few songs from the next artist in line.

    This also happened, when I ran the script on my server, which has a separate internet connection.

    Version info

    • Package version 1.7.0
    • OS: Ubuntu 19.10 (also happened on a 18.04 machine)
    bug 
    opened by Arsanian 12
  • Expected str instance nonetype found

    Expected str instance nonetype found

    My code

    from lyricsgenius import Genius
    
    genius = Genius(xxx)
    
    
    genius.remove_section_headers = True
    
    artist = genius.search_artist(xxx)
    artist.save_lyrics(extension = 'txt', binary_encoding=True)
    
    

    Sometimes script can't find lyrics to one song, passes it and goes to another one. But when saving file, it gives this error:

    Error at line XX: Expected str instance nonetype found genius lyrics

    How do I fix this error so I'm able to save the lyrics, even if one or more is missing?

    opened by NIkitabala 10
  • Created online docs, fixed div class issue used to scrape lyrics

    Created online docs, fixed div class issue used to scrape lyrics

    Documentation

    Have a look at the docs here Considering #63 and the need for docs, I created documentation for the library using Sphinx and also used the RTD theme for it. I used the Google style for documenting the classes, and the functions. Since the library supports all Python 3 versions, I didn't use type hints to auto-document things in Sphinx and added them manually in the docstrings. I also added some examples under the methods, and some more are in the snippets page of the docs. I also added a picture to the index page for aesthetics. I didn't use the Genius logo, because I wasn't sure if using their logo here was allowed or no. This is the first version of the docs, so I'd appreciate any suggestions. To check out the built version of the docs for yourself, install the packages in the requirements file in the docs folder. And then run make html in the same directory (or just use the tox commands below).

    PEP8 Check

    I also did the PEP8 checks, but I'm not sure if all of them contributed to the clarity and style of the code. So feel free to revert any of those. For PEP8, I used flake8 coupled with flake8-bugbear. As for the configs I set for flake8, they're all present in the tox.ini file.

    The dreaded DIV class

    Looks like Genius went and changed up the class of the lyrics' div tag again (#148). I provided two solutions in the mentioned issue, but two users reported that it didn't work for them. But I can't really say anything about that since the fixes both work for me. So I added the second fix to the code.

    Tox

    I added tox so you can check things yourself. Running tox in the source dir of the library will run flake8, doc8 (PEP8 for docs), and create the docs to see if they are created correctly. You can run the following tox commands for the checks:

    • tox - runs flake8, doc8, and tests creating docs
    • tox -e lint - rung flake8 and doc8
    • tox -e docs tests creating docs
    • tox - test runs the tests using pytest (needs GENIUS_CLIENT_ACCESS_TOKEN env var set)

    For tox, I had to edit setup.py, add some things to it, and remove reading the requirements from the text file. But if you don't want to keep the tox file, feel free to revert setup.py and remove the tox file.

    enhancement 
    opened by allerter 10
  • Displaying a list of songs instead of lyrics.

    Displaying a list of songs instead of lyrics.

    Describe the bug When I search for the lyrics of a song it shows me a list of different songs on genius but no the lyrics of the song I specified. I'm using the search_song() function. The title of the song is without any "remix", "live" etc. tags.

    Expected behavior It should be displaying the lyrics of the song not a list of different songs grabbed from genius.

    To Reproduce Describe the steps required to reproduce the behavior.

    1. Search for the song "Post Malone (feat. RANI) by Sam Feldt. genius.search_song("Post Malone (feat. RANI)", "Sam Feldt"
    2. Print the results.
    3. It should be displaying a list of different songs but not lyrics.

    I get no error just the behavior of the module is wrong.

    Version info

    • Package version [1.7.0]
    • OS: [Windows 10 Home 64-bit]

    Additional context It's not happening to every song. Just a few songs have this problem.

    question 
    opened by Qiasm 10
  • Skipping songs taking longer than fetching one

    Skipping songs taking longer than fetching one

    First of all, thanks for the nice program, seems to work well for the most part. I'm trying to build a corpus of lyrics for a project at my university, so I try to fetch all the songs of the artists I want to incorporate. Once the program fetched most of the songs, it seems to find many duplicates and attempts to skip, but skipping takes way longer than fetching a song. Is there any way to speed up the skipping process? Best regards.

    bug enhancement 
    opened by Arsanian 9
  • v3.0

    v3.0

    • Sphinx displayed types attributes using the information in docstrings but they looked a bit messy. So I removed them and manually put them in a table in docs
    • added checking for song_info['instrumental'] when available to avoid fetching lyrics for instrumental songs.
    • renamed album.songs to album.tracks
    • added the Track type (Note: On Genius a track just has the number and song attributes, but since Track inherits BaseEntity it will have a redundant id attribute and Track.id == Track.song.id.)
    • refactored OAuth2 to only support code flow in get_user_token since the token flow already has the token in the redirected url.
    • added release notes to docs (not completed yet)
    enhancement 
    opened by allerter 8
  • Feature request: add a path option to the genius.save_lyrics()-function

    Feature request: add a path option to the genius.save_lyrics()-function

    From my view, there is no option to give the save_lyrics()-function a path or destination, where to save. I think that should be added. If I missed something or someone has a smart workaround, please let me know :)

    enhancement 
    opened by Tr33Bug 1
  • All download/progress lost, when crashing while running the genius.search_artist()-Function.

    All download/progress lost, when crashing while running the genius.search_artist()-Function.

    Describe the bug Write a clear and concise description of what the bug is.

    Expected behavior When the function crashes, I expect to get the fully downloaded lyric files for the artists, witch are completed to the state of crashing.

    To Reproduce My Setup is: I want to download the top 50 lyrics from a list of 100 Artists. Often the function crashes for example at song 20 and all the progress for this artist is lost. After the crash, the return of the function is none.

    Version info

    • Package version: 3.0.1
    • OS: macOS m1 (python 3.9)

    Additional context I have a workaround with a loop to repeat on crash and try every artist max. 10 times. Works for now, but not nice :)

    THX for the great library, by the way. Enjoy using it!

    if you want to see my use in the project, look over to https://github.com/Tr33Bug/ML-NLP-LyricsGen-Transformer

    opened by Tr33Bug 0
  • Is this library abandoned completely?

    Is this library abandoned completely?

    I have a lot of features to offer, however seems this project abandoned completely. And most strange and bad bug I have is: having incorrectly written song name I get completely random song lyrics. Question is: is it worth to make bug reports/pr or it's better to begin to write my own scrapper? Sad story tbh.

    opened by breadfan 5
  • Get random songs from artist

    Get random songs from artist

    Hello,

    I was wondering if it's possible to get random songs from an artist ?

    Something like that:

    artist = genius.search_artist("Andy Shauf", max_songs=3, sort="random")
    print(artist.songs)
    

    Thank you

    opened by Freccia 0
  • add per_page parameter to song_annotations

    add per_page parameter to song_annotations

    TLDR: song_annotations returns only 10 results, I would like to get all annotations for a song.

    I'm performing a text search on all Genius. I get a list of songs that somehow reference the term and I'd like to get alla annotations for these songs (since the term I searched is likely to be there). But the method (https://lyricsgenius.readthedocs.io/en/master/reference/genius.html#lyricsgenius.Genius.song_annotations) returns only 10 results, which 99% of times do not include that very first term I've searched.

    I'd like a parameter to specify how many results to return - and ideally also one for the pagination of results.

    I could not find any docs on Genius how to do this with their API (I cannot even get the 10-result list from that API) Any help would be appreciated! Thank you in advance

    opened by marilenadaquino 0
Releases(3.0.0)
  • 3.0.0(Feb 10, 2021)

    LyricsGenius 3.0.0 is now available.

    New

    • All requests now go through the Sender object. This provides features such as retries genius.retries and handling HTTP and timeout errors. For more info have a look at the guide about request error handling.
    • Added OAuth2 class to help with OAuth2 authentication.
    • Added PublicAPI class to allow accessing methods of the public API (genius.com/api). Check this page for a list of available methods.
    • Added the Album type and the genius.search_album() method.
    • Added the genius.tag() method to get songs by tag.
    • All API endpoints are now supported (e.g. upvote_annotation).
    • New additions to the docs.

    Changed

    • GENIUS_CLIENT_ACCESS_TOKEN env var has been renamed to GENIUS_ACCESS_TOKEN.
    • genius.client_access_token has been renamed to genius.access_token.
    • genius.search_song() will also accept song_id.
    • Lyrics won't be fetched for instrumental songs and their lyrics will be set to "". You can check to see if a song is instrumental using Song.instrumental.
    • Renamed all interface methods to remove redundant get_ (genius.get_song is now genius.song).
    • Renamed the lyrics method to genius.lyrics() to allow use by users. It accepts song URLs and song IDs.
    • Reformatted the types. Some attributes won't be available anymore. More info on the types page.
    • save_lyrics() will save songs with utf8 encoding when extension='txt'.
    • Using Genius() will check for the env var GENIUS_ACCESS_TOKEN.

    Other (CI, etc)

    • Bumped Sphinx to 3.3.0
    Source code(tar.gz)
    Source code(zip)
  • 2.0.1(Sep 23, 2020)

    • Switched to using a regular expression instead of iterating BeautifulSoup's tags manually. The regular expression has better performance.
    • Moved getting new_div inside else body to avoid getting new_div if old_div is present.

    PR: #154

    Source code(tar.gz)
    Source code(zip)
  • 2.0.0(Sep 23, 2020)

    • Added online docs available on Read the Docs
    • Added tests for code styling which use tox and flake8. The docs codes also have their own tests.
    • Fixed finding instances where the lyrics section on the new song page wasn't found (the new_div).

    PR: #153

    Source code(tar.gz)
    Source code(zip)
  • 1.0.0(Dec 1, 2018)

    This release is a result of the substantial cleanup work in PR #69.

    Improvements:

    • Makes substantial clean-ups to API and Genius classes within the api.py
    • Uses the proper exception for catching Timeouts
    • Removes drifting code blocks from search_song
    • Adds support for search_genius_web, the search endpoint used on Genius.com
    • Overhauls search_artist to use the search_genius_web endpoint, improving reliability and robustness of search results
    • Improves the while loop criteria for search_artist
    • Updates README style
    • Minor clean-ups to the song.py and artist.py files (additional work needed)

    Additionally, PR #70 introduced the correct Python approach for handling input from the command line.

    Have at it!

    Source code(tar.gz)
    Source code(zip)
  • 0.5(Jun 11, 2018)

    Changes:

    • User-Agent is now "LyricsGenius"
    • Removing section headers in lyrics is optional now
    • Add option to heuristically remove non-songs (tracklists, credits, etc.)
    • Add the _clean_str() method
    • Add a couple tests
    • General bug fixes and clean-ups
    Source code(tar.gz)
    Source code(zip)
  • 0.4.1(Feb 28, 2018)

    At some point I must have re-introduced a bug that made searching for songs case sensitive. This release fixes that bug. This release also switches the PyPI README file from markdown to RST because PyPI requires RST for proper formatting.

    Source code(tar.gz)
    Source code(zip)
  • 0.4(Feb 27, 2018)

    This release should be much more stable with Unicode issues (as identified in #21 and #24).

    I've also decided to remove Python 2.x support. It just wasn't playing nice enough with Unicode.

    John

    Source code(tar.gz)
    Source code(zip)
  • 0.1(Feb 21, 2018)

Owner
John W. Miller
I, for one, welcome our new computer overlords.
John W. Miller
A library that allows you to easily mock out tests based on AWS infrastructure.

Moto - Mock AWS Services Install $ pip install moto[ec2,s3,all] In a nutshell Moto is a library that allows your tests to easily mock out AWS Services

Steve Pulec 6.5k Jan 02, 2023
Telegram Bot for updating ongoing matches of Fotmob.com in channel by @AbirHasan2005

Fotmob-Bot A very simple Telegram Bot which will update ongoing matches of Fotmob in a channel. Demo Channel Configs API_ID - Get this from @TeleORG_B

Abir Hasan 22 Oct 21, 2022
PyHoroscope - Observational Indian lunisolar calendar, horoscope and matching using the Swiss ephemeris

PyHoroscope Observational Indian lunisolar calendar, horoscope and matching usin

4 Jun 05, 2022
A Python API to retrieve and read MLB GameDay data

mlbgame mlbgame is a Python API to retrieve and read MLB GameDay data. mlbgame works with real time data, getting information as games are being playe

Zach Panzarino 493 Dec 13, 2022
A light wrapper around FedEx's SOAP API.

Python FedEx SOAP API Module Author: Greg Taylor, Radek Wojcik Maintainer: Python FedEx Developers License: BSD Status: Stable What is it? A light wra

155 Dec 16, 2022
A Telegram Bin Checker Bot made with python for check Bin valid or Invalid. 💳

Bin Checker Bot A Telegram Bin Checker Bot made with python for check Bin valid or Invalid. 📌 Deploy On Heroku 🏷 Environment Variables API_ID - Your

Chamindu Denuwan 20 Dec 10, 2022
A file-based quote bot written in Python

Let's Write a Python Quote Bot! This repository will get you started with building a quote bot in Python. It's meant to be used along with the Learnin

1 Nov 01, 2021
Powerful Telegram Maintained UserBot in Telethon

Fire-X UserBot The Awaited Bot Fire-X userbot The Most Powerful Telegram Userbot. This Userbot is Safe to use in Your Telegram Account. It is not like

22 Oct 21, 2022
Cities bot - A simple example of using aiogram and the wikipedia package

Cities game A simple example of using aiogram and the wikipedia package. The bot

Artem Meller 2 Jan 29, 2022
A discord.py extension for sending, receiving and handling ui interactions in discord

discord-ui A discord.py extension for using discord ui/interaction features pip package ▪ read the docs ▪ examples Introduction This is a discord.py u

34 Dec 29, 2022
The best discord Nuk3r !

Discord - Nuker ☢️ Nuk3r ☢️ STEP 1 ✅ We go create discord bot ! [] Go on https://discord.com/developers/applications [] Set the name of your applica

2s.py 1 Apr 16, 2022
Authenticate your League of legends account on riot client in a few lines of code.

lol-authenticator v1.0.0 Content index Project Setup Dependencies Project Setup Dependencies Python v3.9.6 If you don't have Python installed on your

Cássio Fontoura 5 Aug 28, 2022
ro.py is a modern, asynchronous Python 3 wrapper for the Roblox API.

GitHub | Discord | PyPI | Documentation | Examples | License Overview Welcome to ro.py! ro.py is an asynchronous, object-oriented wrapper for the Robl

ro.py 81 Dec 26, 2022
KiKi bare dogs can share your joys and sorrows with you.

Kiki-FangLee-DiscordBot KiKi bare dogs can share your joys and sorrows with you. $help: Kiki will show you my talent, aw-aw. $list: Show Kiki's knowle

Fang Lee 0 Feb 12, 2022
Prometheus exporter for CNMC API

CNMC Prometheus exporter It needs a Prometheus Pushgateway Install requirements via pip install -r requirements.txt Export the following environment v

GISCE-TI 1 Oct 20, 2021
My Advent of Code solutions. I also upload videos of my solves: https://www.youtube.com/channel/UCuWLIm0l4sDpEe28t41WITA

My solutions to adventofcode.com puzzles. I post videos of me solving the puzzles in real-time at https://www.youtube.com/channel/UCuWLIm0l4sDpEe28t41

195 Jan 04, 2023
Twitter-redesign - Twitter Redesign With Django

Twitter Redesign A project that tests Django and React knowledge through a twitt

Mark Jumba 1 Jun 01, 2022
My attempt to reverse the Discord nitro token generation function.

discord-theory-I PART: I My attempt to reverse the Discord nitro token generation function. The Nitro generation tools thing is common in Discord now,

Jakom 29 Aug 14, 2022
A Discord bot for viewing any currency you want comfortably.

Dost Dost is a Discord bot for viewing currencies. Getting Started These instructions will get you a copy of the project up and running on your local

Baran Gökalp 2 Jan 18, 2022
A.I and game for gomoku, working only on windows

Gomoku (A.I of gomoku) The goal of the project is to create an artificial intelligence of gomoku. Goals Beat the opponent. Requirements Python 3.7+ Wo

Luis Rosario 13 Jun 20, 2021