Fix MusicGPT integration: v6/v6-pro models, per-conversion webhooks, store conversion IDs

This commit is contained in:
Troll (Hermes Agent) 2026-08-10 22:53:26 +00:00
parent f185232907
commit 5443c464bd
5 changed files with 81 additions and 43 deletions

View file

@ -343,14 +343,14 @@ def get_musicgpt_api_key():
def get_musicgpt_default_model():
"""Return the configured default MusicGPT model."""
default = current_app.config.get('MUSICGPT_DEFAULT_MODEL', 'v7-pro')
default = current_app.config.get('MUSICGPT_DEFAULT_MODEL', 'v6-pro')
models = get_musicgpt_models()
return default if default in models else models[-1]
def get_musicgpt_models():
"""Return the list of supported MusicGPT models."""
return list(current_app.config.get('MUSICGPT_MODELS', ['v6', 'v6-pro', 'v7', 'v7-pro']))
return list(current_app.config.get('MUSICGPT_MODELS', ['v6', 'v6-pro']))
def build_musicgpt_webhook_url():
@ -629,49 +629,70 @@ def _download_file(url, dest):
return False
def download_musicgpt_outputs(req, data):
def download_musicgpt_outputs(req, data, version=None):
"""
Download the MP3 and WAV outputs from a completed MusicGPT webhook/poll payload.
Updates the request row with local paths and returns a dict of saved paths.
`data` is the conversion dict from the API (may contain conversion_path_1/2 keys).
`data` is the conversion dict from the API. For per-conversion webhooks,
pass `version='A' or 'B'`. For combined payloads, version is auto-detected
from conversion_path_1/2 keys.
"""
request_id = req["id"]
upload_dir = upload_path(request_id)
song_title = req.get("suno_title") or req.get("title")
saved = {}
def _save(url_key, wav_key, field_mp3, field_wav, version):
mp3_url = data.get(url_key)
wav_url = data.get(wav_key)
# Map version label to field names.
def _fields(v):
return ("song_a_path", "song_a_wav_path") if v == "A" else ("song_b_path", "song_b_wav_path")
# Determine which version(s) are present in the payload.
versions = []
if version in ("A", "B"):
versions = [version]
elif data.get("conversion_path_1") or data.get("conversion_path_wav_1"):
if data.get("conversion_path_2") or data.get("conversion_path_wav_2"):
versions = ["A", "B"]
else:
versions = ["A"]
elif data.get("conversion_path_2") or data.get("conversion_path_wav_2"):
versions = ["B"]
elif data.get("conversion_path") or data.get("conversion_path_wav"):
# Per-conversion webhook without explicit version: use the requested version or A.
versions = [version if version in ("A", "B") else "A"]
for v in versions:
field_mp3, field_wav = _fields(v)
url_key = "conversion_path_1" if v == "A" else "conversion_path_2"
wav_key = "conversion_path_wav_1" if v == "A" else "conversion_path_wav_2"
# Also support per-conversion webhook keys without _1/_2 suffix.
if not (data.get(url_key) or data.get(wav_key)):
if v == "A" or version == "A":
mp3_url = data.get("conversion_path")
wav_url = data.get("conversion_path_wav")
else:
mp3_url = data.get("conversion_path")
wav_url = data.get("conversion_path_wav")
else:
mp3_url = data.get(url_key)
wav_url = data.get(wav_key)
if mp3_url:
ext = Path(mp3_url).suffix or ".mp3"
dest = upload_dir / f"{version}{ext}"
dest = upload_dir / f"{v}{ext}"
if _download_file(mp3_url, dest):
apply_mp3_tags(str(dest), song_title)
saved[field_mp3] = str(dest)
if wav_url:
dest_wav = upload_dir / f"{version}.wav"
dest_wav = upload_dir / f"{v}.wav"
if _download_file(wav_url, dest_wav):
saved[field_wav] = str(dest_wav)
_save("conversion_path_1", "conversion_path_wav_1", "song_a_path", "song_a_wav_path", "A")
_save("conversion_path_2", "conversion_path_wav_2", "song_b_path", "song_b_wav_path", "B")
# Album cover
cover_url = data.get("album_cover_path")
if cover_url:
saved["album_cover_url"] = cover_url
# Cost
cost = data.get("conversion_cost")
if cost is None:
# Webhook sample sometimes has conversion_cost string; poll has it nested.
cost = data.get("conversion_cost")
try:
saved["musicgpt_cost"] = float(cost) if cost is not None else None
except (ValueError, TypeError):
saved["musicgpt_cost"] = None
if saved:
update_request(request_id, **saved)
return saved