pyquist.web#
Clients for external music data sources.
freesound#
FreeSound API client.
Most users only need fetch_freesound(), which downloads a sound by URL
or numeric ID and returns it as an pyquist.Audio. Previews download
without authentication; fetching the original uncompressed file requires the
FreeSound OAuth2 flow (walked through interactively on first use).
Credentials and downloaded files are cached under CACHE_DIR / "freesound".
- pyquist.web.freesound.url_to_id(id_or_url)[source]#
Parses a FreeSound URL or numeric ID into an integer sound ID.
Accepted forms:
123456— raw int"123456"— numeric string"https://freesound.org/sounds/123456/""https://freesound.org/people/<user>/sounds/123456/"http://andwww.variants of the above
Raises
ValueErrorif the input isn’t a recognized FreeSound URL or a numeric ID.- Parameters:
id_or_url (int | str)
- Return type:
int
- pyquist.web.freesound.fetch_metadata(sound_id, *, reauthenticate=False)[source]#
Fetches the FreeSound JSON metadata for a sound (cached on disk).
- Parameters:
sound_id (int)
reauthenticate (bool)
- Return type:
dict
- pyquist.web.freesound.fetch_audio_bytes(sound_id, *, preview_tag='preview-hq-ogg', reauthenticate=False)[source]#
Downloads the raw audio bytes for a sound, plus its metadata.
- Parameters:
sound_id (int) – FreeSound numeric ID.
preview_tag (str | None) – Which preview to download. One of
"preview-hq-ogg"(default),"preview-hq-mp3","preview-lq-ogg", or"preview-lq-mp3". PassNoneto download the original uncompressed file instead — this requires OAuth2 and triggers an interactive auth flow on first use.reauthenticate (bool) – Force a re-prompt of API credentials.
- Return type:
Tuple[bytes, dict]
Returns
(audio_bytes, metadata). Both are cached on disk so repeated calls for the same sound are free.
- pyquist.web.freesound.fetch_freesound(id_or_url, *, preview_tag='preview-hq-ogg', reauthenticate=False)[source]#
Fetches an
Audio(and metadata) from FreeSound by URL or numeric ID.Example:
from pyquist.web import fetch_freesound audio, meta = fetch_freesound( "https://freesound.org/people/cdonahueucsd/sounds/337131/" )
- Parameters:
id_or_url (int | str) – A FreeSound URL or numeric sound ID. See
url_to_id()for the recognized URL forms.preview_tag (str | None) – Which preview to fetch (default high-quality OGG). Pass
Noneto fetch the original uncompressed file (OAuth2 required).reauthenticate (bool) – Force a re-prompt of API credentials.
- Returns:
(audio, metadata)—audiois decoded viapyquist.Audio.from_file()andmetadatais the raw JSON dict returned by the FreeSound API.- Return type:
Tuple[Audio, dict]
theorytab#
TheoryTab API client.
TheoryTab is a community database of
pop-song melody and chord progressions hosted by Hooktheory. This module
fetches a song by URL or 11-character ID and turns it into pyquist
pyquist.Score objects ready for rendering.
Most users only need fetch(), which combines fetch_theorytab_json()
(network + caching) with theorytab_json_to_score() (parsing).
Downloaded JSON is cached under CACHE_DIR / "theorytab" so repeat lookups
are free.
- pyquist.web.theorytab.fetch_theorytab_json(id_or_url, *, ignore_cache=False)[source]#
Fetches the raw TheoryTab JSON for a song, caching it on disk.
- Parameters:
id_or_url (str) – A bare 11-character TheoryTab song ID or any URL that contains it as the
idOfSongquery parameter.ignore_cache (bool) – If
True, re-fetch even if a cached copy exists.
- Raises:
ValueError – if
id_or_urlcan’t be parsed.RuntimeError – on a non-200 response from the Hooktheory API or unexpected response shape.
NotImplementedError – if the song’s data is in a legacy format without parsed
jsonData.
- Return type:
dict
- pyquist.web.theorytab.theorytab_json_to_score(song_data, *, durations_in_beats=False, harmony_as_notes=True, melody_octave=5, harmony_octave=4)[source]#
Parses a TheoryTab JSON object into a metronome and two scores.
The
timeof each event is in beats (starting from 0). Pair it with the returnedBasicMetronomewhen rendering so beats are converted to seconds.By default, chord events are emitted as one
Eventper chord tone in root position, each with a"pitch"kwarg — so a triad at beat 4 becomes three events sharingtime == 4.0. Setharmony_as_notes=Falsefor one event per chord instead.- Parameters:
song_data (dict) – TheoryTab JSON (as returned by
fetch_theorytab_json()).durations_in_beats (bool) – If
False(default), each event’skwargs["duration"]is converted to seconds via the song’s tempo. IfTrue, durations stay in beats and the instrument is responsible for any further conversion.harmony_as_notes (bool) – If
True(default), the harmony score holds one event per chord tone, with kwargs{"duration", "pitch"}. IfFalse, it holds one event per chord, with kwargs{"duration", "root", "intervals", "inversion"}—rootis the root’s MIDI pitch,intervalsare the semitone gaps between successive chord tones in root position.melody_octave (int) – Octave offset added to melody pitches.
harmony_octave (int) – Octave offset added to harmony pitches.
- Returns:
(metronome, melody, harmony)wheremetronomeis aBasicMetronomecarrying the song’s tempo, andmelody/harmonyareScoreobjects.- Raises:
NotImplementedError – if the song’s time signature / tempo / key structure is more complex than this parser supports.
- Return type:
- pyquist.web.theorytab.fetch_theorytab(id_or_url, **kwargs)[source]#
Fetches and parses a TheoryTab song in one call.
Equivalent to
theorytab_json_to_score(fetch_theorytab_json(id_or_url), **kwargs).Example:
from pyquist.web import fetch_theorytab metronome, melody, harmony = fetch_theorytab( "https://hookpad.hooktheory.com/?idOfSong=RPxeJeJaob_" )
To get a URL: find a song on TheoryTab, right-click “Open in Hookpad”, and “Copy Link Address.”
- Parameters:
id_or_url (str) – A bare 11-character TheoryTab ID or a Hookpad/Hooktheory URL.
**kwargs – Forwarded to
theorytab_json_to_score().
- Return type: