parse and ParsedTrack
parse(input: string, options?: ParseOptions): ParsedTrackparse(input: str, *, mode="auto", known_artists=(), uploader=None, split_and="auto", keywords=None) -> ParsedTrackparse never throws on a string. Any string gives a ParsedTrack, and unknown or malformed options
fall back to their defaults. (Python raises TypeError if input isn't a str at all.) The options are on the Options page.
ParsedTrack
Section titled “ParsedTrack”Every key is always present. Python has the same fields as attributes of a frozen dataclass, in
snake_case (full_title, flags.unknown_artist), with tuples instead of arrays and None instead
of null.
| Field | Type | |
|---|---|---|
input |
string |
The original string, untouched (not normalised) |
mode |
"clean" | "youtube" | "filename" | "tracklist" |
The mode that actually ran |
position |
{ raw: string, number: number } | null |
Track number. raw is the digits as written ("01") |
timestamp |
{ raw: string, seconds: number } | null |
Leading cue time, "1:02:03" → 3723 |
artists |
Artist[] |
Primary, featured and producer credits. Remixers are in versions |
title |
string |
The clean title. Brackets it doesn't recognise stay in |
fullTitle |
string |
title with the versions put back in their original brackets |
versions |
Version[] |
Remixes and versions, left to right |
year |
number | null |
From (2015) or - 2015 |
flags |
{ explicit, clean, unknownArtist, unknownTitle } |
All booleans |
junk |
{ raw: string, kind: JunkKind }[] |
What was taken out of the title, and what kind of noise it was |
warnings |
Warning[] |
Which heuristics fired. See Warnings |
Artist
Section titled “Artist”{ name: string; role: ArtistRole; joiner: string | null; source: ArtistSource }Artist(name: str, role: ArtistRole, joiner: Optional[str], source: ArtistSource)| Field | Values |
|---|---|
role |
primary, featured, remixer, producer |
joiner |
the text before the name as written ("&", ",", "ft.", "prod. by"), or null for the first name in a list |
source |
artist (left of the dash), title (right of it), version (inside a version) |
&, x and vs. are joiners, not roles. Everyone they join is primary.
Version
Section titled “Version”{ type: VersionType; raw: string; artists: Artist[]; modifiers: VersionType[]; descriptor: string | null; year: number | null; unknownArtist: boolean; delimiter: "(" | "[" | "{" | "-";}Version( type: VersionType, raw: str, artists: tuple[Artist, ...], modifiers: tuple[str, ...], descriptor: Optional[str], year: Optional[int], unknown_artist: bool, delimiter: VersionDelimiter,)| Field | |
|---|---|
type |
one of remix bootleg vip edit flip refix rework mashup blend dub mix extended radio club original instrumental acapella live acoustic remaster demo reprise cover version spedUp slowed nightcore |
raw |
the text inside the brackets, as written |
artists |
remixers (role remixer, source version) |
modifiers |
type words that didn't become the type: Extended VIP Mix → vip, ["extended"] |
descriptor |
leftover words: "Taylor's", "at Wembley", "D'n'B" |
year |
a year inside the version: Remastered 2015 → 2015 |
unknownArtist |
true for ID Remix and the like |
delimiter |
the bracket it was in, or - for a dash suffix |
Versions and remixes explains how the type is chosen.
Junk kinds
Section titled “Junk kinds”video, audio, lyrics, quality, promo, platform, label, genre, other. Examples are
in Junk, flags and prefixes. The vocabulary is in
spec/data.
JSON and Python objects
Section titled “JSON and Python objects”In JavaScript the result is a plain object, so JSON.stringify(track) is the spec's JSON.
In Python, ParsedTrack, Artist, Version, Junk, Flags, Position and Timestamp are
frozen dataclasses. Sequences are tuples, so results are immutable and hashable: you can put them in
sets or use them as dict keys. to_dict() gives the spec's JSON with its camelCase keys, and
from_dict() goes the other way:
import json
json.dumps(track.to_dict(), separators=(",", ":"), ensure_ascii=False)# the same bytes as JSON.stringify(parse(s)) in JavaScript
ParsedTrack.from_dict(track.to_dict()) == track # TrueAll of these are exported from trackparse as TypeScript types:
ParsedTrack, Artist, ArtistRole, ArtistSource, Version, VersionType,
VersionDelimiter, Junk, JunkKind, Flags, Position, Timestamp, Warning, Mode,
ModeOption, ParseOptions, KeywordOptions, FormatOptions.
The package ships py.typed and passes mypy --strict. These are exported from trackparse:
- dataclasses:
ParsedTrack,Artist,Version,Junk,Flags,Position,Timestamp; Literalaliases:ArtistRole,ArtistSource,VersionType,VersionDelimiter,JunkKind,Warning,Mode,ModeOption;TypedDicts for options:ParseOptions,KeywordOptions,FormatOptions;Parser, the classcreate_parserreturns.
The JSON shape is also published as a JSON Schema,
parsed-track.schema.json.