Pythonでステム分離。
Pythonサービスから12行でステム分離を出荷できます。GPUも、モデルダウンロードも、FFmpegも不要です。PyPIの型付きクライアント、このページのFastAPI / Flask webhookハンドラー、そしてすでに信頼している同じhtdemucs_ftモデルを使えます。
インストール
認証
開発者設定ページでキーを発行し、AISTEMSPLITTER_API_KEYとしてexportすると、クライアントが自動的に読み込みます。リクエストごとにキーが必要な場合のみ、コンストラクタへapi_key=を渡してください。デフォルトはenv varが推奨です。
import os
from aistemsplitter import AiStemSplitter
client = AiStemSplitter(api_key=os.environ["AISTEMSPLITTER_API_KEY"])Hello world
importからディスク上の4ステムまで12行です。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)メソッド
SDK全体のsurfaceは、1分以内に把握できる4つの型付きメソッドです。送信、取得、待機、ダウンロード。それぞれが1つのRESTエンドポイントに対応しているため、型付きラッパーを超える必要が出たら、いつでも/developers/apiからraw HTTPへ下りられます。公開モデル: htdemucs_ft、htdemucs、htdemucs_6s。無期限のクレジットパックに対して1分あたり$0.08-$0.14で課金されます。
新しい分離ジョブを送信し、job idとqueuedステータスを返します。
分離ジョブの現在のステータスを取得します。
ジョブが成功、失敗、またはタイムアウトするまでポーリングします。
APIキーに紐づく最近の分離ジョブをページネーション付きで一覧表示します。
ブラウザ/サーバーから直接アップロードするためのpre-signed PUT URLを取得します。
受信webhook payloadのHMAC-SHA256署名を検証します。
Webhooks
本番ではポーリングループを省略できます。送信時にwebhook_urlを設定し、受信POSTのHMAC署名を検証して、本文からpresigned stem URLsを直接読み取ります。同じページにFastAPIとFlaskのハンドラーがあります。
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(StemSplitter)を使ってください。12行のhello worldで使っているものですし、Django viewやCelery taskの中に自然に収まります。すでにFastAPI、Starlette、またはnotebook内のasyncio上にいる場合はAsyncStemSplitterへ切り替えてください。メソッド名は一致しているため(await client.submit、await client.wait、await client.download)、差し替えコストは1つのimportと各呼び出しにつき1つのawaitだけです。
FastAPIとFlaskで動きますか?
はい。どちらもファーストクラスです。上のWebhooksセクションには、それぞれ実行可能なハンドラーがあります。FastAPIはverify_signature付きのasync def webhook(request: Request)、Flaskはsyncの@app.post routeを使います。どちらも1つのimport(from aistemsplitter import verify_signature)でHMAC-SHA256を検証し、追加の解析なしでJSON本文からpresigned stem URLsを取り出します。
virtualenvやPoetryプロジェクトではどうインストールしますか?
標準ツールで対応できます。venvなら`python -m venv .venv && source .venv/bin/activate && pip install aistemsplitter`、Poetryなら`poetry add aistemsplitter`、uvなら`uv add aistemsplitter`です。パッケージはpure-Python wheels(ネイティブコンパイルなし)なので、どのプラットフォームでも数秒でインストールが完了します。pyenv shim、FFmpegの事前手順、GPUドライバーは不要です。
ホスト出力はローカルのhtdemucs_ft品質と一致しますか?
はい。オープンソースコミュニティが信頼する同じモデルファイル、htdemucs_ftに加えてhtdemucsとhtdemucs_6sを公開しています。そのため、同じモデルと同じ入力であれば、当社の管理推論設定(batch size、precision)を除き、ローカルDemucs実行とビット比較可能な出力になります。ギターとピアノのステムが必要な場合は、送信時にmodel='htdemucs_6s'を渡してください。
型付きSDKを超えてraw HTTPが必要になったら?
/developers/apiへ直接下りてください。SDKはcurl quickstartが呼ぶものと同じRESTエンドポイントの薄い型付きラッパーなので、認証ヘッダー(Authorization: Bearer ast_live_…)、webhook署名方式(aistemsplitter-signature内のHMAC-SHA256)、レスポンス形状は同一です。組み合わせも可能です。送信はSDKで呼び、独自のリトライポリシー向けにステータス取得はraw httpxで行えます。
非常に長い音声でタイムアウトしないようにするには?
2つの方法があります。(1)webhooksを使う。送信時にwebhook_urlを設定してポーリングループを完全に省略すれば、長さに関係なくジョブ完了時にAPIが結果をPOSTします。(2)50 MBを超えるファイルではclient.presign_upload()を呼び、ストレージ直通URLを取得し、httpx multipartでアップロードしてから、ゲートウェイを通したストリーミングではなく返却されたaudio_urlで送信します。