Skip to main content

scoreseek

Find a musical score by metadata — across many sources, behind one call.

import scoreseek

hits = scoreseek.search("Cooley's")  # out of the box: The Session (CC-BY-SA)
ref = hits[0]
path = ref.fetch()  # -> a local .abc file
# hand straight to audiate.render(path) to hear it

Every hit is a license-tagged ScoreRef, so public-domain / permissive results stay cleanly separated from copyrighted / gray ones — searches are copyright-safe by default.

Install

pip install scoreseek                # zero required dependencies
pip install "scoreseek[render]"      # + audiate, to render hits to audio

Why

Scores live in many places — public-domain corpora (PDMX, IMSLP, OpenScore), downloadable datasets, chord/lyric collections, and your own folders. scoreseek puts them behind one pluggable-source interface and tags every result with a license, so you can ask for "only what I can legally build on" or opt into copyrighted material explicitly.

Sources

A source answers search(query) -> [ScoreRef] and optionally fetch(ref) -> path. Register any object with that shape.

On by default (zero-config, lightweight, cleanly licensed):

Source What License
thesession thesession.org traditional tunes (ABC) CC-BY-SA 4.0
openscore_lieder ~1,356 OpenScore art songs (compressed MusicXML) CC0

Opt-in (import from scoreseek.sources and register_source(...) — heavier, or license-gated):

Source What License Notes
IMSLPSource IMSLP/Petrucci public-domain classical Public Domain live API; mostly PDF, some MIDI
PDMXSource 250K Public-Domain MusicXML corpus PD / CC0 local corpus — one-time download (see below)
ChordonomiconSource 680K chord progressions CC-BY-NC (gray lane) no title/artist — genre/chord-text search
KaggleChordsSource 135K chords+lyrics songs (via sung) scraped / gray needs Kaggle creds + a ~283 MB download
LocalFolderSource a folder of .mid/MusicXML/ABC/kern files you set it offline
WebMidiSource free-MIDI websites (bitmidi, midis101, midiworld): pop, film, game music scraped / gray HTML scraping, best effort; add sites with MidiSite
LakhMidiSource Lakh MIDI Dataset clean_midi (~17K Artist/Title.mid) scraped / gray local: the 234 MB tarball (searched unextracted) or the folder
from scoreseek import register_source, License
from scoreseek.sources import IMSLPSource, LocalFolderSource

register_source(IMSLPSource())  # opt in to IMSLP
register_source(LocalFolderSource("~/scores", license=License.PUBLIC_DOMAIN))

hits = scoreseek.search("nocturne", composer="Chopin", sources=["imslp"])
hits = scoreseek.search("hey jude", allow_copyrighted=True)  # opt into gray/copyrighted

# film / pop MIDI from the web (gray lane: private study)
from scoreseek.sources import WebMidiSource, LakhMidiSource

register_source(WebMidiSource())
register_source(LakhMidiSource("~/Downloads/clean_midi.tar.gz"))
hits = scoreseek.search("star wars", allow_copyrighted=True)

Canonicalize a messy query (MusicBrainz)

normalize=True resolves a fuzzy "title [+ artist]" to a canonical work via MusicBrainz before searching (adds a ~1 s network round-trip), and stamps the resolved MBID onto each hit:

hits = scoreseek.search("moonlight sonata beethovan", normalize=True)

PDMX: a local public-domain corpus

PDMX ships only as bulk tarballs, so PDMXSource searches a local extraction. Download once (index-only = 225 MB; + MusicXML = ~2.1 GB) from Zenodo record 15571083 and point the source at it:

from scoreseek.sources import PDMXSource

register_source(PDMXSource("~/pdmx"))  # dir with PDMX.csv (+ extracted mxl/, mid/)

search() works with just PDMX.csv; fetch() needs the extracted mxl//mid/ trees and otherwise raises with the exact tarball URL to download.

Write your own source

from scoreseek.sources import Source
from scoreseek.base import License


class MySource(Source):
    name = "mine"
    license = License.CC0

    def search(self, query="", *, title="", composer="", limit=10):
        return [self._ref(title="...", id="...", formats=("musicxml",))]

    def fetch(self, ref, *, fmt=None):
        ...
        return "/path/to/score.musicxml"

License tags

License classifies each hit: PUBLIC_DOMAIN, CC0, PERMISSIVE (CC-BY/-SA, MIT, …), NONCOMMERCIAL (CC-BY-NC), COPYRIGHTED, GRAY (scrapes/unspecified), UNKNOWN.

search(..., allow_copyrighted=False) (the default) is copyright-safe: it returns the commercial-safe lanes (PUBLIC_DOMAIN/CC0/PERMISSIVE) plus UNKNOWN (unclassified provenance, e.g. your own local folders), and drops the restricted lanes — COPYRIGHTED, GRAY, and NONCOMMERCIAL (a known usage restriction). Pass allow_copyrighted=True to include them.

Where it fits

scoreseek is the search stage of a larger pipeline: scoreseek (find a score) → audiate (render to audio) → arioso (AI-enhance).

License

MIT

Metadata

Release files for scoreseek 0.0.4

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for scoreseek 0.0.4
File Size Uploaded
scoreseek-0.0.4.tar.gz 29.0 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for scoreseek 0.0.4
File Interpreter ABI Platform
scoreseek-0.0.4-py3-none-any.whl Python 3 none any Details

Total release size: 68.3 kB

Release files / scoreseek-0.0.4.tar.gz

Download URL scoreseek-0.0.4.tar.gz
Size 29.0 kB
Tags Source
SHA-256 checksum
How to use checksums
33c06f9470e70d186db7a1d511d9de0f0c8bf1ee43281837d748161900bdf449
BLAKE2b-256 checksum
How to use checksums
331d8117d31c7f4f4b0ba944e9781bdc82fdc4044f91792106504b09d9192b09
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.12.22 {"installer":{"name":"uv","version":"0.12.22","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

Release files / scoreseek-0.0.4-py3-none-any.whl

Download URL scoreseek-0.0.4-py3-none-any.whl
Size 39.2 kB
Tags Python 3
SHA-256 checksum
How to use checksums
a18c287725c7e53b6230e40507db306f53040c07937456f4476768bb59df7d5d
BLAKE2b-256 checksum
How to use checksums
7e5d72094f7df8af83e23e34dce9fcd8f7ac4d51b749435d9b15270658e6fe22
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.12.22 {"installer":{"name":"uv","version":"0.12.22","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

Release history Release notifications | RSS feed

This release

0.0.4 This release

2 release files

0.0.3

2 release files

0.0.2

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page