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
Video-Player - Telegram Music/ Video Streaming Bot Using Pytgcalls

Video Player 🔥 ᴢᴀɪᴅ ᴠᴄ ᴘʟᴀyᴇʀ ɪꜱ ᴀ ᴛᴇʟᴇɢʀᴀᴍ ᴘʀᴏᴊᴇᴄᴛ ʙᴀꜱᴇᴅ ᴏɴ ᴘʏʀᴏɢʀᴀᴍ ꜰᴏʀ ᴘʟᴀʏ

Zaid 16 Nov 30, 2022
A simple script that will watch a stream for you and earn the channel points.

Credits Main idea: https://github.com/gottagofaster236/Twitch-Channel-Points-Miner Bet system (Selenium): https://github.com/ClementRoyer/TwitchAutoCo

Alessandro Maggio 1.1k Jan 08, 2023
The Github repository for the Amari API wrapper.

Amari.py Amari.py is an async, easy to use API wrapper for the AmariBot. Installation Enter any of these commands to install the library: pip install

TheF1ng3r 5 Dec 19, 2022
SQS + Lambda를 활용한 문자 메시지 및 이메일, Voice call 호출을 간단하게 구현하는 serverless 템플릿

AWS SQS With Lambda notification 서버 구축을 위한 Poc TODO serverless를 통해 sqs 관련 리소스(람다, sqs) 배포 가능한 템플릿 작성 및 배포 poc차원에서 간단한 rest api 호출을 통한 sqs fifo 큐에 메시지

김세환 4 Aug 08, 2021
Balanced API library in python.

Balanced Online Marketplace Payments v1.x requires Balanced API 1.1. Use v0.x for Balanced API 1.0. Installation pip install balanced Usage View Bala

Balanced 70 Oct 04, 2022
A Python implementation of a Youtube Subscription manager & feed viewer, also does thumbnails

BUILDING Building requires python3.10, and the build package, which can be installed via pip: python3.10 -m pip install build To install, run python3.

2 Feb 28, 2022
Automation application was made by me using Google, Sheet and Slack APIs with Python.

README This application is used to transfer the data in the xlsx document we have to the Google Drive environment and calculate the "total budget" wit

3 Apr 12, 2022
Python3 based bittrex rest api wrapper

bittrex-rest-api This open source project was created to give an understanding of the Bittrex Rest API v1.1/v3.0 in pearl language. The sample file sh

4 Nov 15, 2022
Black-hat with python

black-hat_python Advantages - More advance tool Easy to use allows updating tool update - run bash update.sh Here -: Command to install tool main- clo

Hackers Tech 2 Feb 10, 2022
Randomly selects two teams based on who is in a voice channel on Discord

TeamPickerDiscordBot Randomly selects two teams based on who is in a voice channel on Discord What I Learned The ins and outs of Python as this was my

Brecken Enneking 2 Jan 27, 2022
buys ethereum based on graphics card moving average price on ebay

ebay_trades buys ethereum based on graphics card moving average price on ebay Built as a meme, this application will scrape the first 3 pages of ebay

ConnorCreate 41 Jan 05, 2023
A Telegram Music Bot with proper functions written in Python with Pyrogram and Py-Tgcalls.

⭐️ Yukki Music Bot ⭐️ A Telegram Music Bot written in Python using Pyrogram and Py-Tgcalls Ready to use method A Support Group and ready-to-use runnin

Shikhar Kumar 1000 Jan 03, 2023
An open source development framework to help you build data workflows and modern data architecture on AWS.

AWS DataOps Development Kit (DDK) The AWS DataOps Development Kit is an open source development framework for customers that build data workflows and

Amazon Web Services - Labs 111 Dec 23, 2022
Python library for Seeedstudio Grove devices

grove.py Python library for Seeedstudio Grove Devices on embeded Linux platform, especially good on below platforms: Coral Dev Board (Wiki) NVIDIA Jet

Seeed Studio 123 Dec 17, 2022
Telegram bot that let's you flip a coin in a dialog

coin_flip Telegram bot that let's you flip a coin in a dialog Report issue · Request feature About Software development tool that lets you finally dec

Ivan Akostelov 2 Dec 12, 2021
Maubot azuracast - A maubot to fetch data from your radio station

Maubot Azuracast A maubot to fetch data from your radio station Setup Configure

3 Mar 14, 2022
This bot can mention members upto 10,000 in groups and can mention members upto 200 in channels !

Mention All Bot This bot can mention members upto 10,000 in groups and can mention members upto 200 in channels ! 🏷 Infomation Language: Python. Tele

Anjana Madu 52 Dec 29, 2022
Telegram RAT written in Python

teleRAT Python based RAT that uses Telegram for sending commands and receiving data to and from a victim computer. Setup.py Insert your API key into t

96 Jan 01, 2023
Tamil Voicechat UserBot. Powerd By TamilBots. Https://T.me/TamilSupport

Tamil Voicechat UserBot A Telegram UserBot to Play music 🎶 in Voice Chats. It's recommended to use an USA number.(if your real number is suspended I'

Tamil Bots 78 Nov 01, 2022
Azure Neural Speech Service TTS

Written in Python using the Azure Speech SDK. App.py provides an easy way to create an Text-To-Speech request to Azure Speech and download the wav file. Azure Neural Voices Text-To-Speech enables flu

Rodney 4 Dec 14, 2022