Amir XYZ

Writing some lyrics with the Datamuse API and jq

March 31, 2018

Basically, I copy the JSON result from the Datamuse API into jqplay.org, apply some cool filters to get the words themselves and then: profit!

What is is Datamuse

I don't know what is Datamuse except that they provide a word-querying API for developers or other happy people. You can use a nice endpoint with some query parameters and you get a list of nice words. Head over to their API docs for reference and some explanations.

The queries I most often use look like (notice the queried word):

  1. https://api.datamuse.com/words?rel_rhy=fire&md=s - for rhymes
  2. https://api.datamuse.com/words?rel_rhy=mayhem&md=s - words with similar meaning
  3. https://api.datamuse.com/words?rel_jjb=battlefield&md=s - Adjectives for your lonely nouns

When you put this in your browser or other magic you get a JSON array with objects for each word returned. The &md=s part requests metadata for the number of syllables in each word, which I sometimes use when I know the structure of my sentences. This is where jq comes to play (I'm so witty!) for filtering the JSON happily.

What is is jq and jqplay.org

jq is a command line tool for formatting JSON input. jqplay.org is an online version of it so you won't have to install irrelevant tools on your machine and use the command line all day when you write lyrics (using the command line all day long is great).

You use all kinds of funny filters for transforming the JSON. The jqplay site has examples. Less words more code:

# some filters to use with jq
map(.word)
map(select(.numSyllables == 2) .word)
map({word, numSyllables})

# note I'm not sure if these are optimal
# queries for this kind of transformations.

It means we iterate (map) on all objects in the Datamuse JSON and do magic (.something or select or {...}) selecting data from them.

  1. .word selects only the "word" property from each object giving a nice array of plain words. You can use any property, "word" is something that Datamuse returns in its JSON.
  2. select(...) is a bad name of 'filter' in other normal langauges. What I did here selects words with 2 syllables (which mostly works!).
  3. {...} will take only some properties from the objects. When I skimmed over the examples in jqplay.org they didn't seem to add a '.' before the properties when using this transformation.

But you can use a JSON viewer

Yup.
Please go ahead an use them.

However, this way of doing things is cooler and can be extended to a standalone script. You could then use your command line all day long as you should or make a nice Electron app or real app or whatever.