# BeatPrints turns track metadata and lyrics into a printable poster

> A Python library and CLI that searches Deezer for a track or album, fetches synchronised lyrics from LRClib, and renders a themed poster with Pillow, released under a non-commercial licence.

**TrueMyst/BeatPrints** — ☕ BeatPrints, create eye-catching, Pinterest-style music posters effortlessly.

- Repository: https://github.com/TrueMyst/BeatPrints
- Website: https://beatprints.readthedocs.io/en/latest/
- Stars: 1,068 · Forks: 42
- Language: Python
- License: NOASSERTION
- Published: 2026-10-19 · Updated: 2026-10-19 · Language: en
- Canonical page: https://hysenlabs.com/projects/truemyst-beatprints

## What BeatPrints does, and the problem it was made for

BeatPrints is a Python library with a command line interface that produces Pinterest-style music posters for tracks and albums. The pipeline is the interesting part of the design: it searches a music catalogue for the release, fetches the full metadata, pulls synchronised lyrics from a separate lyrics service, and then renders a poster image with a colour theme applied to it.

The author explains the motivation directly. He noticed that people were selling these posters on Etsy at high prices, offering only digital downloads instead of shipping anything, and he wanted the same result to be free for anyone to print at home. That origin explains several choices in the project, including the deliberately non-commercial licence and the emphasis on themes rather than on selling extra features.

The data sources are named in the README and in the package keywords. The music metadata comes from Deezer, through the deezer-python client, and the lyrics come from the LRClib API through the lrclibapi package. The rendering is done with Pillow, with pylette handling colour and fonttools in the dependency list for font work. The words Spotify appears in the keywords and in the reference to the Etsy listings, but the code talks to Deezer, which is worth noticing if you are looking for a Spotify API client and find this project instead.

The package is published on PyPI as BeatPrints, the version in the packaging metadata is 1.1.9, and the project requires Python 3.12 or newer. The documentation is built with readthedocs and lives at beatprints.readthedocs.io.

## The library API: search, metadata, lyrics, poster

The library is used in three steps, and the README's quick start shows all of them. You initialise the components, you fetch the metadata, and you render.

```python
from BeatPrints import deez, lyrics, poster

# Initialize components
dz = deez.Deezer()
ps = poster.Poster("./")  # Save the poster in the current directory
```

The search takes a query, a type and a limit, and returns results you index into for an identifier:

```python
search = dz.search(query="Apples - Rocco", stype="track", limit=1)

# Grab the Track ID from the first result
id = search[0]["id"]

# Fetch full track metadata
metadata = dz.get_track(id)
```

Lyrics come from the LRClib client wrapped in the lyrics component, and the component does two things with the metadata: it fetches the lyrics and it can tell you whether the track is instrumental:

```python
lrc = lyrics.Lyrics(metadata).get_lyrics()
```

The poster call takes the metadata and the chosen lyrics, and it decides how to compose the image. The track version takes an accent flag and a theme name:

```python
ps.track(metadata=metadata, lyrics=lyrics, accent=False, theme="Light")
```

The album version is the same idea with an indexing flag instead of lyrics, and the README's album example passes accent=True:

```python
ps.album(metadata=metadata, indexing=False, accent=True, theme="Light")
```

The two calls are deliberately similar, which is what you want from a small library. The album poster has no lyrics to place, so the flag in that position is about indexing the tracks, while the accent flag controls the same visual treatment in both.

## Lyrics selection, including the instrumental case

The lyric handling is the part with real logic in it, and the README makes two decisions explicit.

The first is the instrumental case. A track with no lyrics still needs a poster, so the library provides a check, check_instrumental(metadata), and the quick start branches on it, using a placeholder line when the track is instrumental and otherwise picking specific lines:

```python
lyrics = (
    "It's an instrumental track :>"
    if lrc.check_instrumental(metadata)
    else lrc.select_lines("11-14")
)
```

The second is line selection. select_lines takes a range expressed as a string, and the example picks lines 11 to 14, so a poster shows a chosen excerpt rather than an entire lyric sheet. That is the sensible default for a poster, since a page of lyrics is not a poster, and the fact that the range is a string rather than two integers suggests the same call can accept other forms, though the README only documents this one.

The lyrics come from LRClib, which serves synchronised lyrics, and the component wraps the API client rather than implementing the protocol. The practical consequence for a user is that the quality of the poster's text depends on what LRClib has for the track, and there is no fallback path described for a track it does not index. A record with an unusual spelling or a regional title is the kind that can come back empty, and the README does not document an error path for that.

## Themes, the Polaroid filter and the multilingual claim

The visual side is where the project puts its effort. The README says BeatPrints currently offers six additional themes, and the badges name them: Dark, Catppuccin, Gruvbox, Nord, Rosepine and Everforest, all of them colour schemes that come from the terminal and editor communities rather than from print design. The Light theme is the one used in both quick start examples, so it is the default rather than one of the extras.

The feature table lists three further items beside the theming. The Polaroid filter for covers gives the artwork a vintage white-bordered look, which is the visual signature of the genre. Custom cover art lets you supply your own image instead of the default artwork from the catalogue. Multi-language support covers Latin, Hindi, Bengali, Russian, Japanese, Chinese and Korean, and given the fonttools dependency that means the project ships or fetches fonts that can actually draw those scripts, which is the part of multi-language support that usually breaks.

The theme name is passed to the poster call, and the same theme value works for both tracks and albums, so the theme system is a property of the poster component rather than of the release type. The examples directory in the repository holds rendered output for both kinds, with named files for individual tracks and separate folders for tracks and albums, which is a reasonable way to keep a visual regression set.

## The CLI, the packaging and the dependency footprint

The command line entry point is declared in the packaging metadata as beatprints, mapped to cli.prompt:main, and the dependency list includes questionary and rich. The prompt is a video, and the documentation has a CLI page under the guidebook.

Installation offers three routes, and the choice is really about how the dependency set lands in your environment:

```bash
# For pip users
pip install BeatPrints

# For poetry users
poetry add BeatPrints
```

```bash
pipx install BeatPrints
```

The pipx route installs the CLI into its own environment, which is the one to take if you only want the command and do not want the library in a project's virtual environment. The pip and poetry routes install the library itself, which is what you need if you are going to call the API from your own code.

The runtime dependencies are listed in the packaging metadata: requests, pylette, pillow, lrclibapi, fonttools, questionary, rich, toml, deezer-python and typing-extensions. The project is built with poetry-core, and the only development dependency is black, which is also the formatter the project advertises in its badges. The dependency list is moderate for a project of this size, and the two heaviest entries are Pillow and the Deezer client.

One detail is worth flagging for anyone who wants to vendor the code. The packaging metadata sets the licence to CC-BY-NC-4.0, the README describes the project as distributed under the Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License, and the repository metadata reports a custom licence that GitHub cannot classify. Those are three descriptions of one licence field, and the file to read before you rely on any of them is the LICENSE file in the repository root.

## Maintenance, and the licence question that comes with the artwork

The project is not archived, and the last push to the repository was on 2026-06-17, with the v1.1.9 release published the same day. Before that there was v1.1.7 on 2026-06-16 and v1.1.4 on 2025-03-23, so the release history is thin but the recent work is real, and it is concentrated in the poster rendering rather than in the data fetching.

The licence is the part that deserves the most attention in practice. A non-commercial licence means the posters you generate are not a product you can sell, and the share-alike term means the terms travel with the output. For the personal printing case the project was built for, that is exactly right. For anyone who saw the poster as a merchandising opportunity, it is a hard stop, and the README is unambiguous about the intent: the author wanted these to be free for people to print themselves, precisely because he disliked that the originals were being sold as digital downloads.

There is a second licensing question the project does not address, and it is the one that trips up anyone who wants to print these in quantity. The cover art in the poster comes from the Deezer catalogue, and the licence covers the poster template, not the photographs, logos and album art that are placed in it. A poster showing a copyrighted cover is a derivative work of that cover in a way the project cannot license away. The README does not discuss this, and the examples of generated posters in the repository are, in that sense, demonstrations of something whose commercial use is a separate question from the code's licence.

The last limitation is the data dependency. Both halves of the pipeline are live services, Deezer for the metadata and artwork and LRClib for the lyrics, and a poster generator that depends on two network APIs cannot work offline or on demand at scale. Batch generating a set of posters means a lot of requests to both, and the README does not describe any rate limit handling, caching or retry behaviour, so a large run is a set of open questions rather than a documented workflow.

## Conclusion

Adopt BeatPrints if you want printable music posters for personal use, you are comfortable with the library's poster output being your own design, and the non-commercial share-alike terms suit what you plan to do with the result. Do not adopt it for a commercial product line, because the licence is non-commercial and the README's own premise is that the posters should stay free to print. Verify first by installing the package with pip install BeatPrints, then by running the library against one track whose lyrics you know, so you can see exactly how the selected lyric lines are placed on the poster before you generate a batch.

## FAQ

### How do I install BeatPrints?

With pip install BeatPrints, or poetry add BeatPrints, or pipx install BeatPrints if you only want the command line tool in its own environment. The project requires Python 3.12 or newer and is published on PyPI as BeatPrints.

### Which music service does BeatPrints get track and album data from?

Deezer, through the deezer-python client, with the search call taking a query, a type of track or album and a limit, and the identifier from the first result then passed to get_track or get_album. Lyrics come separately from the LRClib API through the lrclibapi package.

### How do I choose which lyrics appear on a BeatPrints poster?

The lyrics component offers select_lines with a line range as a string, and the quick start uses select_lines("11-14"). For an instrumental track there is no lyric to select, so the example calls check_instrumental and falls back to a placeholder line.

### Which themes does BeatPrints offer?

The README lists six additional themes beyond the default Light one: Dark, Catppuccin, Gruvbox, Nord, Rosepine and Everforest. The theme is passed to the poster call, for example ps.track(metadata=metadata, lyrics=lyrics, accent=False, theme="Light").

### Can I sell posters made with BeatPrints?

The project is distributed under a Creative Commons licence with a non-commercial term, and the packaging metadata records the licence as CC-BY-NC-4.0 while the README describes Attribution-NonCommercial-ShareAlike 4.0. The author's stated aim was that the posters stay free to print, so selling them falls outside what the licence grants. The cover artwork comes from the Deezer catalogue and is a separate question from the code's licence.

## Sources

- [Issues](https://github.com/TrueMyst/BeatPrints/issues)
- [Project website](https://beatprints.readthedocs.io/en/latest/)
- [README](https://github.com/TrueMyst/BeatPrints/blob/main/README.md)
- [Releases](https://github.com/TrueMyst/BeatPrints/releases)
- [TrueMyst/BeatPrints on GitHub](https://github.com/TrueMyst/BeatPrints)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/truemyst-beatprints
