├── runtime.txt ├── Procfile ├── .DS_Store ├── STATIC_IMG ├── comic.png └── header1.svg ├── requirements.txt ├── scripts ├── lyrics_hindi.py └── lyrics_english.py ├── main.py ├── .gitignore └── README.md /runtime.txt: -------------------------------------------------------------------------------- 1 | python-3.9.0 -------------------------------------------------------------------------------- /Procfile: -------------------------------------------------------------------------------- 1 | web: gunicorn -w 4 -k uvicorn.workers.UvicornWorker main:app -------------------------------------------------------------------------------- /.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/radioactive11/the-lyrics-api/HEAD/.DS_Store -------------------------------------------------------------------------------- /STATIC_IMG/comic.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/radioactive11/the-lyrics-api/HEAD/STATIC_IMG/comic.png -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | fastapi==0.52.0 2 | pydantic 3 | bs4 4 | requests 5 | lxml 6 | uvicorn[standard] 7 | gunicorn -------------------------------------------------------------------------------- /scripts/lyrics_hindi.py: -------------------------------------------------------------------------------- 1 | import requests 2 | 3 | def fetch_lyrics(artist_name, song_name): 4 | try: 5 | param = song_name + " " + artist_name 6 | param = param.replace(' ', '+') 7 | res = requests.get("https://www.jiosaavn.com/api.php?__call=autocomplete.get&_format=json&_marker=0&includeMetaTags=1&query={param}".format(param = param)).json() 8 | try: 9 | song_id=res['songs']['data'][0]['id'] 10 | res = requests.get("https://www.jiosaavn.com/api.php?__call=lyrics.getLyrics&ctx=web6dot0&api_version=4&_format=json&_marker=0%3F_marker%3D0&lyrics_id={id}".format(id=song_id)).json() 11 | lyrics = res['lyrics'].replace('
', "\n") 12 | return {"lyrics": lyrics} 13 | except: 14 | return {"Error": "Not found"} 15 | except Exception as e: 16 | return {"Error": e} -------------------------------------------------------------------------------- /scripts/lyrics_english.py: -------------------------------------------------------------------------------- 1 | from bs4 import BeautifulSoup 2 | import requests 3 | import re 4 | 5 | def fetch_lyrics(artist_name, song_name): 6 | try: 7 | song_name = re.sub('[\W_]+', '', song_name).lower() 8 | artist_name = re.sub('[\W_]+', '', artist_name).lower() 9 | url = "https://www.azlyrics.com/lyrics/{aname}/{sname}.html".format(aname=artist_name, sname=song_name) 10 | res = requests.get(url) 11 | soup = BeautifulSoup(res.content, 'lxml') 12 | divs = soup.find_all("div", {"class": ""}) 13 | try: 14 | lyrics = divs[1].text 15 | lyrics = lyrics[2: -1] 16 | return {"lyrics": lyrics} 17 | except Exception as e: 18 | print(e) 19 | return {"Error": "Not found"} 20 | 21 | except Exception as e: 22 | print(e) 23 | return {"Error": e} -------------------------------------------------------------------------------- /main.py: -------------------------------------------------------------------------------- 1 | from fastapi import FastAPI 2 | from pydantic import BaseModel 3 | import re 4 | from typing import Optional 5 | from fastapi.middleware.cors import CORSMiddleware 6 | import json 7 | from scripts import lyrics_english, lyrics_hindi 8 | 9 | app = FastAPI() 10 | 11 | class QueryModel(BaseModel): 12 | artist: str 13 | song: str 14 | lang: Optional[str] = 'eng' 15 | 16 | 17 | app = FastAPI() 18 | 19 | 20 | @app.get('/lyrics') 21 | async def get_lyrics(query: QueryModel): 22 | artist_name = query.artist 23 | song_name = query.song 24 | 25 | if query.lang == 'eng': 26 | lyrics = lyrics_english.fetch_lyrics(artist_name, song_name) 27 | return lyrics 28 | 29 | elif query.lang == 'hin': 30 | return lyrics_hindi.fetch_lyrics(artist_name, song_name) 31 | 32 | else: 33 | return {"Error": "undefined value in lang"} 34 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | secret.py 2 | 3 | # Byte-compiled / optimized / DLL files 4 | __pycache__/ 5 | *.py[cod] 6 | *$py.class 7 | 8 | # C extensions 9 | *.so 10 | 11 | # Distribution / packaging 12 | .Python 13 | build/ 14 | develop-eggs/ 15 | dist/ 16 | downloads/ 17 | eggs/ 18 | .eggs/ 19 | lib/ 20 | lib64/ 21 | parts/ 22 | sdist/ 23 | var/ 24 | wheels/ 25 | share/python-wheels/ 26 | *.egg-info/ 27 | .installed.cfg 28 | *.egg 29 | MANIFEST 30 | 31 | # PyInstaller 32 | # Usually these files are written by a python script from a template 33 | # before PyInstaller builds the exe, so as to inject date/other infos into it. 34 | *.manifest 35 | *.spec 36 | 37 | # Installer logs 38 | pip-log.txt 39 | pip-delete-this-directory.txt 40 | 41 | # Unit test / coverage reports 42 | htmlcov/ 43 | .tox/ 44 | .nox/ 45 | .coverage 46 | .coverage.* 47 | .cache 48 | nosetests.xml 49 | coverage.xml 50 | *.cover 51 | *.py,cover 52 | .hypothesis/ 53 | .pytest_cache/ 54 | cover/ 55 | 56 | # Translations 57 | *.mo 58 | *.pot 59 | 60 | # Django stuff: 61 | *.log 62 | local_settings.py 63 | db.sqlite3 64 | db.sqlite3-journal 65 | 66 | # Flask stuff: 67 | instance/ 68 | .webassets-cache 69 | 70 | # Scrapy stuff: 71 | .scrapy 72 | 73 | # Sphinx documentation 74 | docs/_build/ 75 | 76 | # PyBuilder 77 | .pybuilder/ 78 | target/ 79 | 80 | # Jupyter Notebook 81 | .ipynb_checkpoints 82 | 83 | # IPython 84 | profile_default/ 85 | ipython_config.py 86 | 87 | # pyenv 88 | # For a library or package, you might want to ignore these files since the code is 89 | # intended to run in multiple environments; otherwise, check them in: 90 | # .python-version 91 | 92 | # pipenv 93 | # According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control. 94 | # However, in case of collaboration, if having platform-specific dependencies or dependencies 95 | # having no cross-platform support, pipenv may install dependencies that don't work, or not 96 | # install all needed dependencies. 97 | #Pipfile.lock 98 | 99 | # PEP 582; used by e.g. github.com/David-OConnor/pyflow 100 | __pypackages__/ 101 | 102 | # Celery stuff 103 | celerybeat-schedule 104 | celerybeat.pid 105 | 106 | # SageMath parsed files 107 | *.sage.py 108 | 109 | # Environments 110 | .env 111 | .venv 112 | env/ 113 | venv/ 114 | ENV/ 115 | env.bak/ 116 | venv.bak/ 117 | 118 | # Spyder project settings 119 | .spyderproject 120 | .spyproject 121 | 122 | # Rope project settings 123 | .ropeproject 124 | 125 | # mkdocs documentation 126 | /site 127 | 128 | # mypy 129 | .mypy_cache/ 130 | .dmypy.json 131 | dmypy.json 132 | 133 | # Pyre type checker 134 | .pyre/ 135 | 136 | # pytype static type analyzer 137 | .pytype/ 138 | 139 | # Cython debug symbols 140 | cython_debug/ 141 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 |

2 | 3 | [![forthebadge](https://forthebadge.com/images/badges/contains-tasty-spaghetti-code.svg)](https://forthebadge.com) 4 | [![forthebadge](https://forthebadge.com/images/badges/made-with-python.svg)](https://forthebadge.com) 5 | [![forthebadge](https://forthebadge.com/images/badges/powered-by-black-magic.svg)](https://forthebadge.com) 6 | [![forthebadge](https://forthebadge.com/images/badges/you-didnt-ask-for-this.svg)](https://forthebadge.com) 7 |

8 | 9 | 10 |
11 |

12 | 13 | Logo 14 | 15 | 16 | 17 | 18 |

The Lyrics API

19 | 20 |

21 | Get lyrics for English and Hindi songs 22 |
23 |
24 | View Demo 25 | · 26 | Report Bug 27 | · 28 | Request Feature 29 |

30 |

31 | 32 | 33 | 34 | 35 | ## Table of Contents 36 | 37 | * [About the Project](#about-the-project) 38 | * [Getting Started](#getting-started) 39 | * [Prerequisites](#prerequisites) 40 | * [Installation](#installation) 41 | * [Usage](#usage) 42 | * [Product Screenshots](#Product-Screenshots) 43 | * [Roadmap](#roadmap) 44 | * [Contributing](#contributing) 45 | * [Contact](#contact) 46 | 47 | 48 | 49 | 50 | 51 | ## About The Project 52 | 53 | The lack of an working open source API that allows users to fetch lyrics for a song without rate limiting led me to build this. I've hosted this API on Heroku temporarily. Since I'm always use up my monthly *free Heroku dyno hours*, dont be surprised if the the link stops working. I'll find a permanent solution soon. 54 | 55 |
56 | 57 | 58 | 59 | ## Getting Started 60 | 61 | To get a local copy up and running follow these simple example steps. 62 | 63 | ### Prerequisites 64 | 65 | * Python 3.7+ 66 | * FastApi 67 | * BeautifulSoup4 68 | * Uvicorn 69 | 70 | ### Installation 71 | 72 |
73 | 74 | 1. Clone the repo 75 | ```sh 76 | git clone https://github.com/radioactive11/the-lyrics-api 77 | ``` 78 | 79 | 2. Install requirements 80 | ```sh 81 | pip3 install -r requirements.txt 82 | ``` 83 | 84 | 3. Start FastAPI server(by default at `localhost:8000`) 85 | 86 | ```sh 87 | uvicorn main:app 88 | ``` 89 | 90 | ## Usage 91 |
92 | 93 | #### English Songs 94 | 95 | The request body for English songs is: 96 | 97 | ```sh 98 | curl --location --request GET 'https://the-lyrics-api.herokuapp.com/lyrics' \ 99 | --header 'Content-Type: application/json' \ 100 | --data-raw '{ 101 | "artist": "Taylor Swift", 102 | "song": "State of Grace", 103 | "lang": "eng" 104 | }' 105 | ``` 106 | 107 | #### Hindi Songs 108 | 109 | The request body for Hindi songs is: 110 | 111 | ```sh 112 | curl --location --request GET 'https://the-lyrics-api.herokuapp.com/lyrics' \ 113 | --header 'Content-Type: application/json' \ 114 | --data-raw '{ 115 | "artist": "Arijit Singh", 116 | "song": "Darkhaast", 117 | "lang": "hin" 118 | }' 119 | ``` 120 | 121 | *Note: By default, the language parameter is set to English so you can ignore it for English Songs* 122 | 123 | #### Response Format: 124 | ```json 125 | { 126 | "lyrics": "string" 127 | } 128 | ``` 129 | 130 | 131 | ## Roadmap 132 | 133 | See the [open issues](https://github.com/radioactive11/the-lyrics-api/issues) for a list of proposed features (and known issues). 134 | 135 | 136 | 137 | ## Contributing 138 | 139 | Contributions are what make the open source community such an amazing place to be learn, inspire, and create. Any contributions you make are **greatly appreciated**. 140 | 141 | 1. Fork the Project 142 | 2. Create your Feature Branch (`git checkout -b feature/AmazingFeature`) 143 | 3. Commit your Changes (`git commit -m 'Add some AmazingFeature'`) 144 | 4. Push to the Branch (`git push origin feature/AmazingFeature`) 145 | 5. Open a Pull Request 146 | 147 | 148 | 149 | 150 | 151 | 152 | ## Contact 153 | 154 | Arijit Roy - [GitHub](https://github.com/radioactive11) - roy.arijit2001@gmail.com 155 | 156 | 157 | Endpoint: [https://the-lyrics-api.herokuapp.com/lyrics](https://the-lyrics-api.herokuapp.com/) 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | [contributors-shield]: https://img.shields.io/github/contributors/radiaoctive11/HealthBridge.svg?style=flat-square 166 | [contributors-url]: https://github.com/radioactive11/the-lyrics-api/graphs/contributors 167 | [forks-shield]: https://img.shields.io/github/forks/radiaoctive11/HealthBridge.svg?style=flat-square 168 | [forks-url]: https://github.com/radioactive11/the-lyrics-api/network/members 169 | [stars-shield]: https://img.shields.io/github/stars/radiaoctive11/HealthBridge.svg?style=flat-square 170 | [stars-url]: https://github.com/radioactive11/the-lyrics-api/stargazers 171 | [issues-shield]: https://img.shields.io/github/issues/radiaoctive11/HealthBridge.svg?style=flat-square 172 | [issues-url]: https://github.com/radioactive11/the-lyrics-api/issues 173 | [license-shield]: https://img.shields.io/github/license/radiaoctive11/HealthBridge.svg?style=flat-square 174 | [license-url]: https://github.com/radioactive11/the-lyrics-api/blob/master/LICENSE.txt 175 | [linkedin-shield]: https://img.shields.io/badge/-LinkedIn-black.svg?style=flat-square&logo=linkedin&colorB=555 176 | [linkedin-url]: https://linkedin.com/in/othneildrew 177 | [product-screenshot]: STATIC_IMG/ss1.png 178 | 179 | [node-js]: "https://img.shields.io/badge/-JavaScript-F7DF1E?style=flat-square&logo=javascript&logoColor=black" 180 | -------------------------------------------------------------------------------- /STATIC_IMG/header1.svg: -------------------------------------------------------------------------------- 1 | happy_music --------------------------------------------------------------------------------