quotespy: Create graphics for quotes, lyrics, and tweets

José Fernando Costa
Level Up Coding
Published in
6 min readJun 1, 2020

--

In October 2019 I wrote a Medium article on how to create tweet-like graphics using Python and the PIL library. Well, now I’ve released a complete Python library that can be used for that purpose, but also for lyrics and quotes graphics. I called it quotespy.

In this article, I will show you demos based on the examples included in the project’s README, ranging from the most simple usage to a more “advanced” case which integrates quotespy with the os module.

For starters, install the library with the usual pip command

pip install quotespy

And you’ll be good to go.

Creating lyrics/quotes graphics with quotespy.graphics

quotespy comes with two packages, one for tweet-like graphics and another for lyrics/quotes. We’ll go through the latter first.

quotespy.graphics basic usage

As you can see, given only a dictionary with the graphic’s information and a graphic settings (default) format, the above script generates the following .png file.

Basic lyrics graphic sample
Basic lyrics graphic sample

Personally, I don’t think the font (Arial) for the default settings is that good for graphics/lyrics, but I chose it because (1) it’s the font for the tweets package and (2) it’s more commonly available out-of-the-box in possible users’ machines.

Hence, and to improve customization, instead of passing an empty dictionary as the second argument, you can pass your own settings. I call this the graphic_settings dictionary and it includes formatting settings for the graphic. Please take into account that all dictionaries shown here, be it for the graphic’s information or graphical formatting, always require all the key-value pairs included in the examples. Speaking of that, please note that either an empty dictionary or a complete dictionary of custom settings must always be passed as the second positional argument.

quotespy.graphics basic usage with custom graphic settings

As you can see in the snippet above, you can choose the font family, the font size, the dimensions of the graphic (width and height, both in pixels), the color scheme (background and text color, both as Hexadecimal values), the maximum number of characters to have per line, and the vertical margin to leave between lines. Oh, and since we are using custom graphic settings, there’s no need to specify the default_settings_format.

Furthemore, note that the output directory was also specified in this case. When omitted, the created graphic’s destination defaults to the current directory, but when a path is given (either relative or absolute), it is saved in that location. In this instance, the graphic is saved in the “output” folder found in the current directory.

Basic lyrics graphic sample with custom settings
Basic lyrics graphic sample with custom settings

Ideally, a graphic created with the default settings would look like this, using the Inkfree font, but since it is not available by default, I kept Arial for the default settings.

Next up is an example for loading multiples lyrics/quotes from a .txt or .json file to create a graphic for each one. Assuming you have a .json file like this at hand

quotes.json sample file

Or a .txt alternative

quotes.txt sample file

You can use the gen_graphics function to load the file and create a graphic for each quote/lyrics:

quotespy.graphics basic usage for loading multiple quotes

Again, we go with custom graphic settings, and specify a relative path to the .json file of quotes. All quote graphics created are saved in the “output” folder once more. Here is an example of one of the created quote graphics.

Quote graphic example
Quote graphic example

Of course, the same gen_graphics function could be used for a lyrics file. The variable factor here is the graphic settings used, the text is simply what is drawn in the graphic.

And that’s pretty much it for the graphics package. Now let’s move on to the tweet_graphics counterpart.

Creating tweet graphics with quotespy.tweet_graphics

Creating tweet graphics is equally simple, with just some added key-value pairs for the information and graphic settings dictionaries.

For starters, the tweet_info dictionary requires the name of the tweet/file (instead of title), the username and tag/handle of the user and, of course, the actual tweet’s text. The path to a profile picture can also be added or, alternatively, left as an empty string.

tweet_graphics basic usage

In this case, the profile picture is available in a “samples” folder, under the name “user_photo.png”, that is, it’s location is specified with a relative path. Oh, and please note that the profile picture is resized to a tenth of the graphic’s dimensions, with a circular crop.

Akin to the graphics package, the create_tweet function also accepts default graphic settings: “blue”, “light” and “dark”, which mirror Twitter’s themes. Below is the output graphic of the code snippet shown.

tweet_graphics basic usage example output
tweet_graphics basic usage example output

And, of course, it is possible to pass custom graphic settings.

Basic quotespy.tweet_graphics usage with custom graphic settings

Note how the graphic_settings dictionary for tweets includes font_size_text and font_size_header keys, so the header (username and tag/handle) can be of a different size from the rest of the tweet.

This time the graphic is saved in the current directory, and it doesn’t have a profile picture:

Basic tweet graphic sample with custom settings
Basic tweet graphic sample with custom settings

Finally, it is also possible to load a file with multiple tweets, but this time only .json files.

Assuming you have a file like this (an array of JSON objects which are loaded as a list of graphic_info dictionaries):

tweets.json sample file

It is then possible to generate graphics for each tweet in the file with this code:

Which creates two graphics, one for each tweet in the file, using the default “light” theme graphic settings. The second one looks like this:

gen_tweet example output

I’m showing the second tweet graphic so you can see how the graphics look like for a long username and text.

“Advanced usage”

Lastly, I’d like to show an “advanced usage” example which integrates quotespy with the os module to create both “light” and “dark” mode graphics of tweets, in a folder for each tweet.

quotespy advanced usage

Firstly, there is a list of tweet_info dictionaries, that is, a list of tweets. The “top-level” save destination is the “output” folder once again, specified in the PATH variable. Afterwards, two custom graphic settings dictionaries are specified: one for the light mode and another for the dark mode.

Now that all the information is settled down, we can loop through the list of tweets to create each one with the create_tweet function. However, before creating any graphic we create a new folder in “output” to store both versions (light and dark) of the current tweet. This is achieved by creating a folder of the same name as the tweet through os.path.join and the mkdir terminal command (executed through os.system).

Finally, the light mode version is created and, to create the dark counterpart, “_DM” is appended to the tweet’s name in order to have a different name for each version. If the name was the same, the dark mode version would overwrite the light mode version.

After running the script, the “output” folder now contains three folders, one for each tweet, with a dark and light version in each.

Conclusion

Writing this library was a valuable experience. First and foremost, I believe I created an interesting library that can help people get content ready to post on social media. Second, I learned a lot creating it. I have been doing these creations with independent scripts locally, but now the code is publicly available for usage.

Another great thing from this project was getting acquainted with the pytest testing library. It’s flexible and allows for fast writing of automated tests, with small overhead for writing variations of the same test (for instance, testing which exception a function throws for different graphic_settings dictionaries). Unfortunately I didn’t get to write all the tests I wanted to, but at least the library has a good enough code coverage (around 80%).

Lastly, I’d like to point in the direction of the “Python project maturity checklist”, by Michał Karzyński. It truly was a great guide to go from detached script to a finalized library ready to be published.

quotespy is available on GitHub here and in PyPi here.

--

--