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
This is a starter template of discord.py project

Template Discord.py This is a starter template of discord.py project (Supports Slash commands!). 👀 Getting Started First, you need to install Python

1 Dec 22, 2021
An alternative to OpenFaaS nats-queue-worker for long-running functions

OpenFaas Job Worker OpenFaas Job Worker is a fork of project : OSCAR Worker - https://github.com/grycap/oscar-worker Thanks to Sebástian Risco @srisco

Sebastien Aucouturier 1 Jan 07, 2022
A Python script to create customised Spotify playlists using the JSON, Spotipy Library and Spotify Web API, based on seed tracks in your history.

A Python script to create customised Spotify playlists using the JSON, Spotipy Library and Spotify Web API, based on seed tracks in your history.

Youngseo Park 1 Feb 01, 2022
Discord bot built using Python. through this you can get information about the upcoming matches, scoreboard, live score

IPL-bot This is a Discord bot built using Python. through this you can get information about the upcoming matches, scoreboard, live score, and many mo

0 Dec 23, 2021
Discord Bot for server hosts, devs, and admins. Analyzes timings reports & uploads text files to hastebin. Developed by https://birdflop.com.

"Botflop" Click here to invite Botflop to your server. Current abilities Analyze timings reports Paste a timings report to review an in-depth descript

Purpur 76 Dec 31, 2022
Py hec token mgr - Create HEC tokens in Cribl Stream through the API

Add HEC tokens via API calls This script is intended as an example of how to aut

Jon Rust 3 Mar 04, 2022
Reddit bot for r/khiphop

khiphop-bot Description This project is a collection of scripts that better the state of the r/khiphop subreddit, which represents Korean Hip-Hop and

1 Dec 21, 2021
Discord bot that manages expiration of roles with subscriptions!

Discord bot that manages expiration of roles with subscriptions!

Chakeaw__ 3 Apr 28, 2022
Web3 Ethereum DeFi toolkit for smart contracts, Uniswap and PancakeSwap trades, Ethereum JSON-RPC utilities, wallets and automated test suites.

Web3 Ethereum Defi This project contains common Ethereum smart contracts and utilities, for trading, wallets,automated test suites and backend integra

Trading Strategy 222 Jan 04, 2023
Telegram bot to download almost all from Instagram

Instagram Manager Bot The most advanced Instagram Downloader Bot. Please fork this repository don't import code Made with Python3 (C) @subinps Copyrig

SUBIN 300 Dec 30, 2022
light wrapper for indeed.com api

Simple wrapper for indeed api. go to indeed.com - register for api publisher token example from indeed import IndeedApi token = 'your token' api =

16 Sep 21, 2022
Telegram bot with various Sticker Tools

Sticker Tools Bot @Sticker_Tools_Bot A star ⭐ from you means a lot to us! Telegram bot with various Sticker Tools Usage Deploy to Heroku Tap on above

Stark Bots 20 Dec 08, 2022
MemeBot - A discord bot that tracks how good people's memes are

MemeBot A discord Meme "Karma" Tracking bot Dependancies Make sure you have pymongo installed and a mongodb cluster setup with two collections. pip in

Uday Sharma 3 Aug 10, 2022
Soundcloud Music Downloader

Soundcloud Music Downloader Description This script is able to download music from SoundCloud and set id3tag to the downloaded music. Compatible with

Ronan 2.6k Jan 01, 2023
This is a telegram bot built using the Oxford Dictionary API

Oxford Dictionaries Telegram Bot This is a telegram bot built using the Oxford Dictionary API Source: Oxford Dictionaries API Documentation Install En

Abhijith N T 2 Mar 18, 2022
Campsite Reservation Cancellation Finder (Yellowstone National Park)

yellowstone-camping yellowstone-camping is a Campsite Reservation Cancellation Finder for Yellowstone National Park. This simple Python application wi

Justin Flannery 7 Aug 05, 2022
Snipe fair coin launches. Contact @dannsniper on telegram for whitelist

Pancakeswap-sniper Pancakeswap Sniper bot Full version of Pancakeswap sniping bot used to snipe during fair coin launches. With advanced options and a

36 Nov 01, 2021
Easy-apply-bot - A LinkedIn Easy Apply bot to help with my job search.

easy-apply-bot A LinkedIn Easy Apply bot to help with my job search. Getting Started First, clone the repository somewhere onto your computer, or down

Matthew Alunni 5 Dec 09, 2022
Wetterdienst - Open weather data for humans

We are a group of like-minded people trying to make access to weather data in Python feel like a warm summer breeze, similar to other projects like rdwd for the R language, which originally drew our

226 Jan 04, 2023