Python client and command-line tool for the AudioShake API: stem separation, dialogue isolation, speech clean-up, multi-speaker separation, music detection and removal, lyric transcription and alignment.
pip install audioshake # library + CLI
uvx audioshake run song.wav -m vocals,drums # or run the CLI with no install- Library:
AudioShakeandAsyncAudioShakeclients, typed results, precise exceptions, automatic retries, one-callrun()or the individual API steps. - CLI:
audioshake runfor files, folders and URLs with a live progress tree,--jsonfor scripts,audioshake modelsandaudioshake tasksto explore your account. - Python 3.10+, typed (
py.typed), tested on 3.10 through 3.15. - Version 0.x: the surface is settling; breaking changes are called out in the changelog and bump the minor version.
Authenticate either with an API key from the
AudioShake dashboard, exported as
AUDIOSHAKE_API_KEY, or by signing in from the terminal with audioshake login.
from audioshake import AudioShake
with AudioShake() as client: # reads AUDIOSHAKE_API_KEY
result = client.run("song.wav", ["vocals", "drums"], output_dir="stems/song")
print(result.task.cost) # credits charged
print([str(f) for f in result.files]) # stems/song/vocals.wav, stems/song/drums.wavrun() uploads the file (or passes a URL through), creates the task, waits for
it and downloads the outputs into output_dir as <output>.<format>, for
example vocals.wav. Give each source its own directory; the CLI does that for
you with one sub-directory per source. Every step is also available on its own:
from audioshake import AudioShake, Target
with AudioShake() as client:
for model in client.models.list():
print(model.id, model.credits_per_minute, model.output_formats)
asset = client.assets.upload("interview.mp3")
task = client.tasks.create(
asset,
[
Target("multi_voice", num_speakers=3),
Target("transcription", formats=("json",), language="en"),
],
)
task = client.tasks.wait(task.id, on_poll=lambda t: print(t.done))
client.tasks.download(task, "out/")The async client has the same surface:
import asyncio
from audioshake import AsyncAudioShake
async def main():
async with AsyncAudioShake() as client:
results = await asyncio.gather(
client.run("a.wav", ["vocals"], output_dir="out/a"),
client.run("b.wav", ["vocals"], output_dir="out/b"),
)
asyncio.run(main())Errors are typed, so you can catch what you can handle:
from audioshake import AudioShake, AuthenticationError, TaskFailedError
try:
with AudioShake() as client:
result = client.run("song.wav", ["vocals", "drums"], output_dir="stems/song")
for target in result.failed: # some models failed; the rest were downloaded
print(target.model, target.error)
except TaskFailedError as e: # every model failed
print(e.task.failed[0].error) # the API's reason
except AuthenticationError:
...Connection errors, timeouts, rate limits and 5xx responses are retried with
backoff before an exception reaches you. Task creation is billed, so it is only
retried when the API declined to act (408, 425, 429, 503). The library logs to
the audioshake logger and never prints.
Full reference: docs/library.md.
audioshake run song.wav -m vocals,drums -o stems/
audioshake run ./album -m effects,dialogue,music_fx -f mp3 --residual
audioshake run https://example.com/talk.mp3 -m transcription --language en
audioshake run panel.wav -m multi_voice --num-speakers 3
audioshake models # what your account can run, with cost and formats
audioshake tasks list # recent tasks
audioshake tasks get TASK_ID
audioshake tasks download TASK_ID -o out/run takes any number of files, directories (-r to recurse) and public URLs,
processes them concurrently (-c, default 10), and writes
OUT/<source>/<output>.<format>, the layout Demucs and Spleeter use. In a
terminal it paints a live tree with one row per source and per model;
elsewhere, or with --plain, it logs lines instead.
Logs go to stderr; results go to stdout. --json makes the results
machine-readable (run prints one JSON object per source):
audioshake --json run song.wav -m vocals | jq .files
audioshake --json models | jq '.[].id'Exit codes: 0 success, 1 a source failed or partly completed, 2 usage
error, 3 authentication, 4 network failure after retries, 5 unexpected
error, 130 interrupted.
Full reference, every option and the output layout: docs/cli.md.
| Library | pip install audioshake or uv add audioshake |
| CLI, no install | uvx audioshake ... |
| CLI, on your PATH | uv tool install audioshake or pipx install audioshake |
| From source | git clone https://github.com/audioshake/audioshake-python && cd audioshake-python && uv sync |
Two credentials work everywhere; the first one found wins:
- An API key:
--api-key, orAUDIOSHAKE_API_KEYin the environment (what CI and scripts should use). - A browser sign-in session:
audioshake loginopens the AudioShake sign-in page, caches the session in~/.audioshake/credentials.json(mode 600) and refreshes it silently until its refresh token expires.
audioshake login # opens the browser
audioshake login --no-browser # prints the URL (on stderr) instead
audioshake whoami # which credential is in use, and who you are
audioshake logoutUnder the hood login is the OAuth 2.0 authorization-code flow with PKCE: the
CLI listens on 127.0.0.1 for the redirect, exchanges the code for tokens, and
sends them to the API as Authorization: Bearer. From Python, use
audioshake.auth.login() and pass the token to AudioShake(bearer_token=...).
AUDIOSHAKE_BASE_URL points the library at another API host.
Model ids are passed through to the API, which is the source of truth for what
exists; audioshake models lists the current catalogue with cost per minute,
output formats, supported languages and input limits. Text models
(transcription, alignment, music_detection, music_identification)
produce JSON by default; audio models produce WAV unless you ask for another
format. Several models run from one upload: -m effects,dialogue,music_fx gives
the dialogue, music and effects stems, -m vocals_backing,vocals_lead the two
vocal stems.
The plugin/ folder is a plugin for Claude Code and Codex that teaches the
agent to use the CLI and library. Install it from the AudioShake marketplace.
Inside Claude Code:
/plugin marketplace add audioshake/plugins
/plugin install audioshake-cli@audioshake
From your shell, for Codex:
codex plugin marketplace add audioshake/plugins
codex plugin add audioshake-cli@audioshakeThen ask for stems, an instrumental, isolated dialogue or lyrics from a file and
the agent runs audioshake for you. The skill is kept in step with the CLI by
tests/test_skill_docs.py.
uv sync # environment with dev dependencies
uv run pytest # tests (HTTP is mocked; no key needed)
uv run ruff check . && uv run ruff format --check .
uv run mypy # strict on the libraryCI runs the same on Python 3.10 to 3.15. Releases are published to PyPI from
v* tags. See
CONTRIBUTING.md
before opening an issue or a pull request. Design notes are in
docs/design.md.
- API documentation
- Issues
- MIT License, © AudioShake, Inc.