在 Python 里做 stem 分离。
用 12 行代码从你的 Python service 发布 stem separation——无需 GPU、无需下载模型、无需 FFmpeg。PyPI 上的 typed client,本页提供 FastAPI 和 Flask webhook handlers,并使用你已经信任的同一个 htdemucs_ft 模型。
安装
认证
在 developer settings 页面创建一个 key,然后 export 为 AISTEMSPLITTER_API_KEY,让 client 自动读取。只有当你需要每次请求使用不同 key 时,才在 constructor 里传 api_key=——默认推荐 env var。
import os
from aistemsplitter import AiStemSplitter
client = AiStemSplitter(api_key=os.environ["AISTEMSPLITTER_API_KEY"])Hello world
从 imports 到磁盘上的 4 条 stem,只要 12 行。提交一个 job 到 htdemucs_ft,轮询到完成,然后把 vocals.wav、drums.wav、bass.wav 和 other.wav 写到脚本旁边。复制、粘贴、运行。
import os
import requests
from aistemsplitter import AiStemSplitter
client = AiStemSplitter(api_key=os.environ["AISTEMSPLITTER_API_KEY"])
# 1. Submit a split job
job = client.create_split(
input={"type": "direct_url", "url": "https://example.com/song.mp3"},
stem_model="htdemucs_ft",
)
# 2. Wait until completion (polls under the hood)
result = client.wait_for_split(job.id)
# 3. Download all six stems to disk
for name, url in result.stems.items():
with requests.get(url, stream=True) as r:
with open(f"./{name}.wav", "wb") as f:
for chunk in r.iter_content(chunk_size=8192):
f.write(chunk)Methods
完整 SDK surface 只有 4 个 typed methods,1 分钟内就能看完——submit、get、wait、download。每个 method 都映射一个 REST endpoint,所以当 typed wrapper 不够用时,可以随时下探到 /developers/api 的 raw HTTP。暴露的模型:htdemucs_ft、htdemucs、htdemucs_6s。按输入分钟从永不过期的积分包扣费,每分钟 $0.08–$0.14。
提交新的 split job;返回 job id 和 queued status。
获取某个 split job 的当前状态。
持续轮询,直到 job 成功、失败或超时。
按页列出这个 API key 最近的 split jobs。
获取 pre-signed PUT URL,用于浏览器/服务器直接上传。
验证传入 webhook payload 上的 HMAC-SHA256 signature。
Webhooks
生产环境里跳过轮询循环。在 submit 时设置 webhook_url,然后验证传入 POST 的 HMAC signature,并直接从 body 中读取 presigned stem URLs。同一页提供 FastAPI 和 Flask handlers。
import os
from fastapi import FastAPI, Request, HTTPException
from aistemsplitter import AiStemSplitter
app = FastAPI()
client = AiStemSplitter(api_key=os.environ["AISTEMSPLITTER_API_KEY"])
@app.post("/webhooks/aistemsplitter")
async def handle_webhook(request: Request):
raw = await request.body()
try:
event = client.verify_webhook(request.headers, raw)
except Exception:
raise HTTPException(status_code=400, detail="invalid signature")
if event.type == "split.succeeded":
# event.data["stems"] -> six URLs
pass
elif event.type == "split.failed":
# event.data["error"] -> { code, message }
pass
return {"ok": True}FAQ
Should I use the sync client or the async one?
Default to sync (StemSplitter) — that's what the 12-line hello world uses, and it's what fits naturally inside a Django view or a Celery task. Switch to AsyncStemSplitter when you're already on FastAPI, Starlette, or asyncio in a notebook: the method names match (await client.submit, await client.wait, await client.download), so swapping costs one import + one await per call.
Does it work with FastAPI and Flask?
Yes — both are first-class. The Webhooks section above ships runnable handlers for each: FastAPI uses async def webhook(request: Request) with verify_signature; Flask uses a sync @app.post route. Both verify HMAC-SHA256 with one import (from aistemsplitter import verify_signature) and unpack presigned stem URLs from the JSON body without extra parsing.
How do I install in a virtualenv or Poetry project?
Standard tooling: `python -m venv .venv && source .venv/bin/activate && pip install aistemsplitter` for venv; `poetry add aistemsplitter` for Poetry; `uv add aistemsplitter` for uv. The package is pure-Python wheels (no native compilation), so installation completes in seconds on every platform — no pyenv shim, no FFmpeg pre-step, no GPU driver.
Will hosted output match my local htdemucs_ft quality?
Yes. We expose the same model file the open-source community trusts — htdemucs_ft, plus htdemucs and htdemucs_6s — so output is bit-comparable to a local Demucs run with the same model + same input, modulo our managed inference settings (batch size, precision). Pass model='htdemucs_6s' on submit when you need guitar and piano stems.
What if I outgrow the typed SDK and need raw HTTP?
Drop straight to /developers/api. The SDK is a thin typed wrapper over the same REST endpoints the curl quickstart calls, so the auth header (Authorization: Bearer ast_live_…), the webhook signature scheme (HMAC-SHA256 in aistemsplitter-signature), and the response shapes are identical. You can mix-and-match — call submit via the SDK, fetch status via raw httpx for a custom retry policy.
How do I handle very long audio without timing out?
Two strategies. (1) Use webhooks — set webhook_url on submit and skip the polling loop entirely; the API posts results when the job finishes regardless of duration. (2) For files larger than 50 MB, call client.presign_upload() to get a direct-to-storage URL, upload via httpx multipart, then submit with the returned audio_url instead of streaming through our gateway.
我应该用 sync client 还是 async client?
默认用 sync(StemSplitter)——12 行 hello world 用的就是它,也自然适合 Django view 或 Celery task。当你已经在 FastAPI、Starlette 或 notebook 里的 asyncio 环境中时,再切换到 AsyncStemSplitter:method names 保持一致(await client.submit、await client.wait、await client.download),所以替换成本只有一个 import 加每次调用一个 await。
它能配合 FastAPI 和 Flask 使用吗?
可以——两者都是 first-class。上方 Webhooks 部分为每个框架提供可运行 handler:FastAPI 使用 async def webhook(request: Request) 搭配 verify_signature;Flask 使用 sync @app.post route。两者都通过一个 import(from aistemsplitter import verify_signature)验证 HMAC-SHA256,并从 JSON body 中解包 presigned stem URLs,无需额外解析。
如何安装到 virtualenv 或 Poetry project?
使用标准工具即可:venv 用 `python -m venv .venv && source .venv/bin/activate && pip install aistemsplitter`;Poetry 用 `poetry add aistemsplitter`;uv 用 `uv add aistemsplitter`。这个 package 是 pure-Python wheels(无需 native compilation),所以每个平台上都能几秒完成安装——不需要 pyenv shim、不需要 FFmpeg 预步骤,也不需要 GPU driver。
托管输出会和我本地 htdemucs_ft 的质量一致吗?
会。我们暴露的是开源社区信任的同一个模型文件——htdemucs_ft,以及 htdemucs 和 htdemucs_6s——所以在相同模型和相同输入下,输出可以与本地 Demucs 运行结果做 bit-comparable 对比,差异只来自我们的 managed inference settings(batch size、precision)。当你需要 guitar 和 piano stem 时,在 submit 时传 model='htdemucs_6s'。
如果 typed SDK 不够用、需要 raw HTTP 怎么办?
直接切到 /developers/api。SDK 只是同一套 REST endpoints 上的 thin typed wrapper,也就是 curl quickstart 调用的同一套接口,所以 auth header(Authorization: Bearer ast_live_…)、webhook signature scheme(aistemsplitter-signature 中的 HMAC-SHA256)和 response shapes 都完全一致。你可以混用——用 SDK submit,用 raw httpx fetch status 来实现自定义 retry policy。
如何处理很长的音频,避免 timeout?
两种策略。1)使用 webhooks——submit 时设置 webhook_url,完全跳过轮询循环;无论时长多久,API 都会在 job 完成后 POST 结果。2)对于大于 50 MB 的文件,调用 client.presign_upload() 获取 direct-to-storage URL,通过 httpx multipart 上传,然后用返回的 audio_url submit,而不是把文件流经我们的 gateway。
下一步
在 sprint 结束前交付 stem separation。
创建 key 无需绑卡。免费额度覆盖前 10 分钟;之后使用永不过期的积分包——按购买量不同,每分钟 $0.08–$0.14。