Developer Documentation

The documentation in this section describes the internal workings of Troi. Developers wishing to use Troi shouldn’t need to know about these modules, but if you wish to extend the core functionality of Troi, this documentation is for you!

Note: There are some modules in troi directory that are not covered here – those are important for end users, so thos are defined in the main section of our docs.

troi.cli

This module is the entry point for the troi command line interface.

troi.core

Troi core module that creates and executes the patches:

troi.patch

Troi patch class definition:

class troi.patch.Patch(args)
abstract create(input_args)

The function creates the data pipeline and then returns it.

Params:

input_args: the arguments passed to the patch.

static description()

Return the description for this patch – this short description (not more than a paragraph) should give the user an idea as to what the patch does.

e.g “Generate a list of random recordings from a given area.”

generate_playlist()

Generate a playlist

The args parameter is a dict and may containt the following keys:

  • quiet: Do not print out anything

  • save: The save option causes the generated playlist to be saved to disk.

  • token: Auth token to use when using the LB API. Required for submitting playlists to the server. See https://listenbrainz.org/profile to get your user token.

  • upload: Whether or not to submit the finished playlist to the LB server. Token must be set for this to work.

  • created-for: If this option is specified, it must give a valid user name and the TOKEN argument must specify a user who is whitelisted as a playlist bot at listenbrainz.org .

  • name: Override the algorithms that generate a playlist name and use this name instead.

  • desc: Override the algorithms that generate a playlist description and use this description instead.

  • min-recordings: The minimum number of recordings that must be present in a playlist to consider it complete. If it doesn’t have sufficient numbers of tracks, ignore the playlist and don’t submit it. Default: Off, a playlist with at least one track will be considere complete.

  • spotify: if present, attempt to submit the playlist to spotify as well. should be a dict and contain the spotify user id, spotify auth token with appropriate permissions, whether the playlist should be public, private or collaborative. it can also optionally have the existing urls to update playlists instead of creating new ones.

Parameters:

args – the arguments to pass to the patch, may contain one of more of the following keys:

get_service(slug)

Given a service slug, return the class registered for this service.

Raises IndexError if no such service is registered.

static inputs()

This function should return a list of dicts that defined the type (argument or option), args, and kwargs to be passed to the click function. MusicBrainz entities and python base types can all be used. The documentation of the method is used as the help returned by the command. Example:

[
    {
        "type" : "argument",
        "args": ["num_recordings"],
        "kwargs": {
            "optional": true
        }
    }
]
is_local()

If this function returns True, it means that the patch expects to use the local database, so Troi should setup the local database before running this patch. Returns False unless overridden by a deriving patch.

post_process()

This function is called once the pipeline has produced its playlist, just before the Playlist object is created. This function could be used to inspect data in patch local storage to create the detailed playlist name and descriptionm which may not be available when the pipeline is constructed.

register_service(service)

Register a new service that can provide services to troi patches.

Only one service can be registered for any given service slug at a time. The most recently registered service will be use for the next playlist generation.

static slug()

Return the slug for this patch – this is a URL friendly short identifier that can be used to invoke this patch via an HTTP call.

e.g area-random-recordings

user_feedback()

Call this function to retrieve a list of strings that give the user feedback about the playlist that was generated, if any.

troi.playlist

Troi playlist class that creates and serializes playlists:

troi.print_recording

Debugging module for printing out the information associated with recordings:

class troi.print_recording.PrintRecordingList

Print a list of recordings in a sane matter intended to fit on a reasonably sized screen. It prints recording name and artist name always, and year, bpm, listen_count or moods if they are found in the first recording.

print(entity)

Print out a list(Recording) or list(Playlist).

troi.utils

Misc functions needed to run troi:

troi.utils.discover_patches()

Attempt to load patches from the installed patches dir as well as any patches directory in the current dir.

troi.utils.discover_patches_from_dir(module_path, patch_dir, add_dot=False)

Load patches given the appropriate python module path and then file system path. If add_dot = True, add . to the sys.path and then remove it before this function exists.

troi.utils.interleave(lists)

Return a list with all items from the given lists.

troi.utils.recursively_update_dict(source, overrides)

Updates the source dictionary in place and in a recursive fashion. That is unlike dict1.update(dict2) which would simply replace values of keys even in case one of the values is dict, this method will attempt to merge the nested dicts.

Eg: dict1 - {“a”: {“b”: 1}}, dict2 - {“a”: {“c”: 2}} dict1.update(dict2) - {“a”: {“c”: 2}} recursively_update_dict(dict1, dict2) - {“a”: {“b”: 1, “c”: 2}}