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 simple discord bot written in python which can surf subreddits, send a random meme, jokes and also weather of a given place

A simple Discord Bot A simple discord bot written in python which can surf subreddits, send a random meme, jokes and also weather of a given place. We

1 Jan 24, 2022
An interactive App to play with Spotify data, both from the Spotify Web API and from CSV datasets.

An interactive App to play with Spotify data, both from the Spotify Web API and from CSV datasets.

Caio Lang 3 Jan 24, 2022
Telegram Userbot to steram youtube live or Youtube vido in telegram vc by help of pytgcalls

TGVCVidioPlayerUB Telegram Userbot to steram youtube live or youtube vidio in telegram vc by help of pytgcalls Commands = Vidio Playing 🎧 stream :

Achu biju 3 Oct 28, 2022
BroBot's files, code and tester.

README - BroBOT Made by Rohan Chaturvedi [email protected] DISCLAIMER: Th

1 Jan 09, 2022
Holly ♥️ is usefull group management bot in telegram 🎋

Holly ♥️ is usefull group management bot in telegram 🎋

Kasun bandara 1 Dec 03, 2021
Based on falcondai and fenhl's Python snowflake tool, but with documentation and simliarities to Discord.

python-snowflake-2 Based on falcondai and fenhl's Python snowflake tool, but with documentation and simliarities to Discord. Docs make_snowflake This

2 Mar 19, 2022
Modern Desktop Jellyfin Client written in Python and Vue for the UI [WIP]

JellyPlayer Modern Jellyfin Client Installation Install Requirements: Install Python 3 Install dependencies Install node deps for frontend, go to Jell

Prayag Prajapati 57 Dec 12, 2022
Auto like & auto followers facebook

Auto like & auto followers facebook

Fahmi Dev 23 Dec 08, 2022
See trending stock tickers on Reddit and check Stock perfomance

See trending stock tickers on Reddit and check Stock perfomance

Abbas 1.5k Jan 06, 2023
Automated crypto trading bot as adapted from Algovibes.

crypto-trading-bot Automated crypto trading bot as adapted from Algovibes. Pre-requisites Ensure that you have created a Binance API key before procee

Kai Koh 33 Nov 01, 2022
Chatbot with python code!

Chatbot Python Chatbot with python! How to Run Installation requirements. pip install -r requirements.txt Sample Chatbot The required files must be d

Mohammad Dori 3 Jul 15, 2022
Clisd.py - UI framework with client side rendering for python

clisd.py Clisd is UI framework with client side rendering for python. It uses WA

2 Mar 25, 2022
Prime Mega is a modular bot running on python3 with autobots theme and have a lot features.

PRIME MEGA Prime Mega is a modular bot running on python3 with autobots theme and have a lot features. Easiest Way To Deploy On Heroku This Bot is Cre

『TØNIC』 乂 ₭ILLΣR 45 Dec 15, 2022
Properly-formatted dynamic timestamps for Discord messages

discord-timestamps discord-timestamps generates properly-formatted dynamic timestamps for Discord messages, with support for Arrow objects. format

Ben Soyka 2 Mar 10, 2022
OpenAPI Generator allows generation of API client libraries (SDK generation), server stubs, documentation and configuration automatically given an OpenAPI Spec (v2, v3)

OpenAPI Generator Master (5.3.1): 5.4.x (5.4.x): 6.0.x (6.0.x): ⭐ ⭐ ⭐ If you would like to contribute, please refer to guidelines and a list of open t

OpenAPI Tools 14.8k Jan 04, 2023
Crud-python-sqlite: used to manage telephone contacts through python and sqlite

crud-python-sqlite This program is used to manage telephone contacts through python and sqlite. Dependencicas python3 sqlite3 Installation Clone the r

Luis Negrón 0 Jan 24, 2022
b2blaze

b2blaze Welcome to the b2blaze library for Python. Backblaze B2 provides the cheapest cloud object storage and transfer available on the internet. Com

George Sibble 603 Jan 03, 2023
A demo without 🚀 science, just simple UTXO spending logic.

Stuck TX Demo Docker container that runs 4 dogecoind to demonstrate "the stuck tx problem". Scenario A wallet sends out 3 transactions to a recipient

Patrick Lodder 2 Nov 16, 2021
📷 An Instagram bot written in Python using Selenium on Google Chrome

📷 An Instagram bot written in Python using Selenium on Google Chrome. It will go through posts in hashtag(s) and like and comment on them.

anniedotexe 47 Dec 19, 2022
Its The Basic Commands Of Termux

Its The Basic Commands Of Termux

ANKIT KUMAR 1 Dec 27, 2021