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 Telegram bot for Download songs in mp3 format from YouTube and Extract lyrics from Genius.com ❤️

MeudsaMusic A Telegram bot for Download songs in mp3 format from YouTube and Extract lyrics from Genius.com ❤️ Commands Reach @MedusaMusic on Telegram

Bibee 14 Oct 6, 2022
PyLyrics Is An [Open-Source] Bot That Can Help You Get Song Lyrics

PyLyrics-Bot Telegram Bot To Search Song Lyrics From Genuis. ?? Demo: ??‍?? Deploy: ❤ Deploy Your Own Bot : Star ?? Fork ?? & Deploy -Easy Way -Self-h

DAMIEN 12 Nov 12, 2022
A Telegram Bot That Can Find Lyrics Of Song

Lyrics-Search-Bot A Telegram Bot That Can Find Lyrics Of Song A Simple Telegram Bot That Can Extract Lyrics Of Any Songs Deploy Commands start - To St

Muhammed Fazin 11 Oct 21, 2022
LyricsGenius: a Python client for the Genius.com API

LyricsGenius: a Python client for the Genius.com API lyricsgenius provides a simple interface to the song, artist, and lyrics data stored on Genius.co

KevinChunye 2 Jun 30, 2022
Converts between Spotify's new lyrics (and their proprietary format) to an LRC file for local playback.

spotify-lyrics-to-lrc Converts between Spotify's new lyrics (and their proprietary format) to an LRC file for local playback. How to use: Open Spotify

~noah~ 6 Nov 19, 2022
A module to get data about anime characters, news, info, lyrics and more.

Animec A module to get data about anime characters, news, info, lyrics and more. The module scrapes myanimelist to parse requested data. If you wish t

DriftAsimov 31 Aug 31, 2022
Find songs by lyrics.

LyricSearch Hi, welcome to LyricSearch - a simple (Yes), fast (Maybe), and powerful (Approach) lyric search engine. We support Three search methods to

Dicer_ 1 Dec 13, 2021
Changes the Telegram bio, profile picture, first and last name to the song that the user is currently listening to.

TGBIOFY - Telegram & Spotify integration Changes the Telegram bio, profile picture, first and last name to the song that the user is currently listeni

elpideus 26 Dec 7, 2022
A code to match you with the perfect Taylor Swift song for your mood and relationship status.

taylorswift A package for matching your current mood and relationship status to a suitable Taylor Swift song. Requirements: Python 2 or 3, and the num

Megan Mansfield 82 Dec 9, 2022
SongFinder Bot helps you to find song name by recognising via voice note or instagram reels shared link.

SongFinder V1.1 SongFinder to detect songs name by just sending voice note or instagram reels links to your telegram bot. FFMPEG must be installed on

Abhishek Pathak 4 Dec 30, 2022
BLYRIC is a Twitter bot that tweets a song lyric every night.

BLYRIC BLYRIC, a bot that tweets a song lyric every night. Follow on Twitter: @blyric_ Overview BLYRIC is a Twitter bot that tweets a song quote every

Bruno Kenzo Hyodo 6 Oct 5, 2022
scrapes medias, likes, followers, tags and all metadata. Inspired by instagram-php-scraper,bot

instagram_scraper This is a minimalistic Instagram scraper written in Python. It can fetch media, accounts, videos, comments etc. `Comment` and `Like`

sirjoe 2.5k Nov 16, 2022
Enumerate Microsoft 365 Groups in a tenant with their metadata

Enumerate Microsoft 365 Groups in a tenant with their metadata Description The all_groups.py script allows to enumerate all Microsoft 365 Groups in a

Clément Notin 46 Dec 26, 2022
Python CMR is an easy to use wrapper to the NASA EOSDIS Common Metadata Repository API.

This repository is a copy of jddeal/python_cmr which is no longer maintained. It has been copied here with the permission of the original author for t

NASA 9 Nov 16, 2022
Centralized whale instance using github actions, sourcing metadata from bigquery-public-data.

Whale Demo Instance: Bigquery Public Data This is a fully-functioning demo instance of the whale data catalog, actively scraping data from Bigquery's

Hyperquery 17 Dec 14, 2022
SickNerd aims to slowly enumerate Google Dorks via the googlesearch API then requests found pages for metadata

CLI tool for making Google Dorking a passive recon experience. With the ability to fetch and filter dorks from GHDB.

Jake Wnuk 21 Jan 2, 2023
Telegram PHub Bot using ARQ Api and Pyrogram. This Bot can Download and Send PHub HQ videos in Telegram using ARQ API.

Tg_PHub_Bot Telegram PHub Bot using ARQ Api and Pyrogram. This Bot can Download and Send PHub HQ videos in Telegram using ARQ API. OS Support All linu

TheProgrammerCat 13 Oct 21, 2022
Command-line program to download videos from YouTube.com and other video sites

youtube-dl - download videos from youtube.com or other video platforms INSTALLATION DESCRIPTION OPTIONS CONFIGURATION OUTPUT TEMPLATE FORMAT SELECTION

youtube-dl 116.4k Jan 7, 2023
Command-line program to download image galleries and collections from several image hosting sites

gallery-dl gallery-dl is a command-line program to download image galleries and collections from several image hosting sites (see Supported Sites). It

Mike Fährmann 6.4k Jan 6, 2023