Skip to main content

venice_ai.resources.music

Venice AI Music API resources.

This module provides classes for interacting with the Venice AI Music generation API. Music generation uses the same async queue family as video (submit / retrieve / cancel), wired against the /audio/queue|quote|retrieve|complete endpoints. The high-level :class:MusicJob context manager handles the lifecycle for you.

Pre-v2.0.0 these methods lived on client.audio alongside TTS / ASR; they're now their own resource so the namespace mirrors the rest of the SDK (one resource = one content domain).

MusicJob Objects

class MusicJob()

Manages the lifecycle of an async music generation request.

Use as an async context manager to guarantee server-side cleanup:

async with VeniceClient() as client:
model = await client.models.resolve_music()
async with await client.music.run(
model=model,
prompt="Uplifting cinematic orchestral opener, 30 seconds",
duration_seconds=30,
) as job:
status = await job.wait()
await job.download("opener.mp3", status)

MusicJob.__aexit__

async def __aexit__(exc_type: type[BaseException] | None,
_exc_val: BaseException | None, _exc_tb: object) -> None

Guarantee server-side cleanup on exit. Mirrors VideoJob.

MusicJob.status

@property
def status() -> MusicRetrieveResponse | None

Last known status from polling.

Returns:

The most recent :class:MusicRetrieveResponse returned by :meth:poll, or None if the job has not yet been polled.

MusicJob.is_complete

@property
def is_complete() -> bool

Whether the most recent poll returned a completed status.

Returns:

True if :attr:status is a :class:MusicCompletedStatus, otherwise False (also False before the first poll).

MusicJob.is_failed

@property
def is_failed() -> bool

Whether the most recent poll returned a failed status.

Returns:

True if :attr:status is a :class:MusicFailedStatus, otherwise False (also False before the first poll).

MusicJob.progress

@property
def progress() -> float | None

Progress as a 0.0-1.0 fraction while processing, else None.

Returns:

status.progress_percent / 100 when the last poll returned a :class:MusicProcessingStatus. Returns None for terminal states (completed / failed) and before the first poll.

MusicJob.poll

async def poll() -> MusicRetrieveResponse

Single poll - retrieve current status.

Wraps POST /api/v1/audio/retrieve for this job's queue_id.

Returns:

The current :class:MusicRetrieveResponse (one of :class:MusicProcessingStatus, :class:MusicFailedStatus, or :class:MusicCompletedStatus). Also caches the result on :attr:status.

Raises:

  • APIError - For HTTP-level failures retrieving the queue entry (mapped subclasses include AuthenticationError, RateLimitError, NotFoundError).

MusicJob.wait

async def wait(
*,
poll_interval: float = 5.0,
max_polls: int = 120,
on_progress: Callable[[MusicProcessingStatus], None] | None = None
) -> MusicCompletedStatus

Poll until complete or failed.

Drives :meth:poll on a fixed interval, returning the final :class:MusicCompletedStatus once the server reports completion.

Arguments:

  • poll_interval - Seconds to sleep between successive polls. Defaults to 5.0.
  • max_polls - Maximum number of polls before giving up. Defaults to 120 (i.e. ten minutes at the default interval).
  • on_progress - Optional callback invoked after every poll that returns a :class:MusicProcessingStatus - useful for forwarding progress to logs or a UI.

Returns:

The terminal :class:MusicCompletedStatus.

Raises:

  • MusicGenerationError - If the server reports generation failure.
  • TimeoutError - If max_polls is exhausted before completion.
  • APIError - For HTTP-level failures while polling.

MusicJob.download

async def download(path: str | Path, status: MusicCompletedStatus) -> Path

Download a completed music clip to path.

Does NOT call :meth:cancel - use the context manager for that. File I/O is offloaded to a worker thread so the event loop never blocks. URL downloads reuse the SDK client's managed HTTP session so proxy, SSL, timeout, and retry configuration are honored.

Arguments:

  • path - Target file path. Parent directories are created automatically (mkdir -p).
  • status - A terminal :class:MusicCompletedStatus returned from :meth:wait or :meth:poll. The bytes are sourced from status.data when present, or fetched from status.url.

Returns:

The resolved :class:pathlib.Path the audio was written to.

Raises:

  • APIError - If the URL fetch fails (mapped subclasses include APIConnectionError, APITimeoutError).
  • OSError - If the file cannot be written (permission denied, disk full, etc.).

MusicJob.cancel

async def cancel() -> MusicCompleteResponse

Release server-side storage / cancel an in-progress job.

Wraps POST /api/v1/audio/complete, which deletes the queue entry server-side regardless of whether generation has finished. Named cancel (rather than the wire-format complete) to distinguish it from the :attr:is_complete state check - terminal states are polled via :meth:wait / :attr:status.

Returns:

:class:MusicCompleteResponse confirming the queue entry was released.

Raises:

  • APIError - For HTTP-level failures (mapped subclasses include AuthenticationError, NotFoundError if the queue id no longer exists).

Music Objects

class Music(APIResource["VeniceClient"])

Asynchronous interface for Venice AI's Music generation API.

Mirrors :class:venice_ai.resources.video.Video: submit queues a job, run returns a managed :class:MusicJob, retrieve polls, cancel releases server-side storage, quote gives a price estimate.

Accessed through :attr:venice_ai.VeniceClient.music.

Music.submit

async def submit(*,
model: str,
prompt: str,
lyrics_prompt: str | None = None,
duration_seconds: int | str | None = None,
force_instrumental: bool | None = None,
lyrics_optimizer: bool | None = None,
voice: str | None = None,
language_code: str | None = None,
speed: float | None = None) -> MusicQueueResponse

Queue a music generation request.

Wraps POST /api/v1/audio/queue. Call :meth:quote first for a price estimate, then poll :meth:retrieve with the returned queue_id to fetch the audio. Or use :meth:run to get a managed :class:MusicJob that handles the lifecycle.

Parameter support varies by model - inspect /models?type=music for per-model capability fields (supports_lyrics, supports_speed, etc.).

Arguments:

  • model - Music model id (e.g. resolved via client.models.resolve_music()).
  • prompt - Natural-language description of the desired track.
  • lyrics_prompt - Optional separate prompt to drive the lyrics on vocal-capable models.
  • duration_seconds - Target clip duration. Accepts an int or a stringified int; server caps vary by model.
  • force_instrumental - If True, suppresses vocals even when the model would otherwise sing. Defaults to None (model default applies).
  • lyrics_optimizer - If True, asks the model to refine lyrics for prosody/syllable count. Defaults to None.
  • voice - Named voice preset for vocal-capable models.
  • language_code - BCP-47 language hint for the lyrics (e.g. "en", "ja").
  • speed - Playback-speed multiplier where supported.

Returns:

:class:MusicQueueResponse containing the queue_id to poll with :meth:retrieve and the echoed model id.

Raises:

  • InvalidRequestError - If the model id fails validation, the prompt is empty, or any parameter is rejected server-side.
  • AuthenticationError - If the API key is missing or invalid.
  • RateLimitError - If the music queue is saturated for the account.
  • APIError - For other HTTP-level failures.

Music.quote

async def quote(*,
model: str,
duration_seconds: int | str | None = None,
character_count: int | None = None) -> MusicQuoteResponse

Get a price quote for a music generation request.

Wraps POST /api/v1/audio/quote. Use this before :meth:submit to surface cost in your UI without committing to a generation.

Arguments:

  • model - Music model id whose pricing to look up.
  • duration_seconds - Target clip duration to price. Accepts an int or stringified int.
  • character_count - Optional character count for lyrics-priced models that bill per syllable / character.

Returns:

:class:MusicQuoteResponse with the estimated cost breakdown for the request.

Raises:

  • InvalidRequestError - If the model id fails validation or the request is rejected server-side.
  • AuthenticationError - If the API key is missing or invalid.
  • APIError - For other HTTP-level failures.

Music.retrieve

async def retrieve(
*,
model: str,
queue_id: str,
delete_media_on_completion: bool = False) -> MusicRetrieveResponse

Retrieve the result of a music generation request.

Poll POST /api/v1/audio/retrieve until the audio is ready. When the API streams the audio inline as binary, the bytes are attached to the completed status's private data buffer.

Arguments:

  • model - Music model id used at submit time.
  • queue_id - Queue identifier returned by :meth:submit.
  • delete_media_on_completion - If True, the server releases the cached audio after this retrieval (a one-shot fetch). Defaults to False so the URL remains downloadable on subsequent polls.

Returns:

One of :class:MusicProcessingStatus, :class:MusicFailedStatus, or :class:MusicCompletedStatus, keyed off the response's status field. Inline binary payloads are attached to MusicCompletedStatus._data.

Raises:

  • InvalidRequestError - If the model id or queue id fails validation server-side.
  • AuthenticationError - If the API key is missing or invalid.
  • NotFoundError - If the queue id does not exist or has been released.
  • ValueError - If the response cannot be parsed into any of the three status shapes.
  • APIError - For other HTTP-level failures.

Music.cancel

async def cancel(*, model: str, queue_id: str) -> MusicCompleteResponse

Release server-side storage / cancel an in-progress job.

Wraps POST /api/v1/audio/complete. Named cancel (rather than the wire-format complete) to distinguish it from :attr:MusicJob.is_complete state checks.

Arguments:

  • model - Music model id used at submit time.
  • queue_id - Queue identifier returned by :meth:submit.

Returns:

:class:MusicCompleteResponse confirming the queue entry was released.

Raises:

  • InvalidRequestError - If the model id or queue id fails validation server-side.
  • AuthenticationError - If the API key is missing or invalid.
  • NotFoundError - If the queue id no longer exists.
  • APIError - For other HTTP-level failures.

Music.run

async def run(*,
model: str,
prompt: str,
lyrics_prompt: str | None = None,
duration_seconds: int | str | None = None,
force_instrumental: bool | None = None,
lyrics_optimizer: bool | None = None,
voice: str | None = None,
language_code: str | None = None,
speed: float | None = None) -> MusicJob

Submit a music generation and return a managed :class:MusicJob.

Calls :meth:submit then wraps the queue response in a :class:MusicJob async context manager. On exit, the SDK calls :meth:MusicJob.cancel to release server-side storage. Accepts the same parameters as :meth:submit.

Wraps POST /api/v1/audio/queue (the lifecycle context manager also touches /audio/retrieve and /audio/complete).

Arguments:

  • model - Music model id (e.g. resolved via client.models.resolve_music()).
  • prompt - Natural-language description of the desired track.
  • lyrics_prompt - Optional separate prompt to drive the lyrics on vocal-capable models.
  • duration_seconds - Target clip duration. Accepts an int or a stringified int.
  • force_instrumental - If True, suppresses vocals.
  • lyrics_optimizer - If True, asks the model to refine lyrics for prosody/syllable count.
  • voice - Named voice preset for vocal-capable models.
  • language_code - BCP-47 language hint for the lyrics.
  • speed - Playback-speed multiplier where supported.

Returns:

A :class:MusicJob ready to use as an async context manager.

Raises:

  • InvalidRequestError - If the model id fails validation, the prompt is empty, or any parameter is rejected server-side.
  • AuthenticationError - If the API key is missing or invalid.
  • RateLimitError - If the music queue is saturated for the account.
  • APIError - For other HTTP-level failures.

Example:

.. code-block:: python

from venice_ai import VeniceClient

async with VeniceClient() as client: model = await client.models.resolve_music() async with await client.music.run( model=model, prompt="Upbeat synthwave track with driving bass", duration_seconds=45, ) as job: status = await job.wait() await job.download("track.mp3", status)