Skip to content

mistral_common.protocol.transcription.request

StreamingMode

Bases: str, Enum

Streaming behavior for a transcription request.

Attributes:

Name Type Description
DISABLED

No streaming; the full transcript is returned once complete.

ONLINE

Audio is streamed to the server and the transcription is streamed back incrementally.

OFFLINE

Audio is sent in one go and the transcription is streamed back.

TranscriptionRequest(**data)

Bases: BaseCompletionRequest

A request for audio transcription.

Attributes:

Name Type Description
id str | None

Optional identifier for this transcription request.

model str | None

The model to use for transcription. If None, the serving side default transcription model is used.

audio str | bytes

Audio data to transcribe. Either raw audio bytes or a base64-encoded string (decoded automatically).

language LanguageAlpha2 | None

Language of the input audio in ISO-639-1 format (e.g., "en"). If provided, improves language adherence of the transcript.

strict_audio_validation bool

If True (default), audio data is validated against the expected format and raises on invalid input. If False, best-effort decoding is attempted.

streaming StreamingMode

The streaming mode for the request. See StreamingMode.

target_streaming_delay_ms int | None

When streaming is enabled, the target delay in milliseconds between hearing a word and producing its transcript. This is a request, not a guarantee; unsupported models ignore it.

Source code in pydantic/main.py
def __init__(self, /, **data: Any) -> None:
    """Create a new model by parsing and validating input data from keyword arguments.

    Raises [`ValidationError`][pydantic_core.ValidationError] if the input data cannot be
    validated to form a valid model.

    `self` is explicitly positional-only to allow `self` as a field name.
    """
    # `__tracebackhide__` tells pytest and some other tools to omit this function from tracebacks
    __tracebackhide__ = True
    validated_self = self.__pydantic_validator__.validate_python(data, self_instance=self)
    if self is not validated_self:
        warnings.warn(
            'A custom validator is returning a value other than `self`.\n'
            "Returning anything other than `self` from a top level model validator isn't supported when validating via `__init__`.\n"
            'See the `model_validator` docs (https://docs.pydantic.dev/latest/concepts/validators/#model-validators) for more details.',
            stacklevel=2,
        )

from_openai(openai_request, strict=False) classmethod

Create a TranscriptionRequest from an OpenAI request dictionary.

The "file" entry is read (BytesIO or file-like object with a .file attribute), decoded via Audio, and re-encoded as a base64 string.

Parameters:

Name Type Description Default
openai_request dict[str, Any]

Dictionary matching OpenAI's transcription request schema. Must contain a "file" entry.

required
strict bool

If True, audio data is strictly validated during decoding.

False

Returns:

Type Description
TranscriptionRequest

A TranscriptionRequest instance with the audio base64-encoded.

Raises:

Type Description
AssertionError

If no "file" entry is present.

Source code in src/mistral_common/protocol/transcription/request.py
@classmethod
def from_openai(cls, openai_request: dict[str, Any], strict: bool = False) -> "TranscriptionRequest":
    r"""Create a TranscriptionRequest from an OpenAI request dictionary.

    The "file" entry is read (BytesIO or file-like object with a .file
    attribute), decoded via Audio, and re-encoded as a base64 string.

    Args:
        openai_request: Dictionary matching OpenAI's transcription request
            schema. Must contain a "file" entry.
        strict: If `True`, audio data is strictly validated during decoding.

    Returns:
        A TranscriptionRequest instance with the audio base64-encoded.

    Raises:
        AssertionError: If no "file" entry is present.
    """
    file = openai_request.get("file")
    seed = openai_request.get("seed")
    converted_dict = {
        k: v
        for k, v in openai_request.items()
        if (k in cls.model_fields and not (v is None and k in ["temperature", "top_p"]))
    }

    assert file is not None, file
    if isinstance(file, io.BytesIO):
        audio_bytes = file.getvalue()
    else:
        # for example if file is UploadFile, this should work
        audio_bytes = file.file.read()

    audio = Audio.from_bytes(audio_bytes, strict=strict)
    audio_str = audio.to_base64(audio.format)

    converted_dict["audio"] = audio_str
    converted_dict["random_seed"] = seed
    return cls(**converted_dict)

to_openai(exclude=(), **kwargs)

Convert the transcription request into the OpenAI format.

Audio is converted into an in-memory file buffer with the correct format extension, and mistral-specific fields are dropped.

Parameters:

Name Type Description Default
exclude tuple

Extra field names to exclude from the output, in addition to the mistral-specific defaults ("id", max_tokens, strict_audio_validation, "streaming").

()
kwargs Any

Additional OpenAI parameters merged into the output.

{}

Returns:

Type Description
dict[str, list[dict[str, Any]]]

The request in the OpenAI format, with the audio under the "file" key

dict[str, list[dict[str, Any]]]

and random_seed renamed to "seed".

Raises:

Type Description
ImportError

If soundfile is not installed.

Source code in src/mistral_common/protocol/transcription/request.py
def to_openai(self, exclude: tuple = (), **kwargs: Any) -> dict[str, list[dict[str, Any]]]:
    r"""Convert the transcription request into the OpenAI format.

    Audio is converted into an in-memory file buffer with the correct format
    extension, and mistral-specific fields are dropped.

    Args:
        exclude: Extra field names to exclude from the output, in addition to
            the mistral-specific defaults ("id", `max_tokens`,
            `strict_audio_validation`, "streaming").
        kwargs: Additional OpenAI parameters merged into the output.

    Returns:
        The request in the OpenAI format, with the audio under the "file" key
        and `random_seed` renamed to "seed".

    Raises:
        ImportError: If soundfile is not installed.
    """
    openai_request: dict[str, Any] = self.model_dump(exclude={"audio"})

    assert_soundfile_installed()

    if isinstance(self.audio, bytes):
        buffer = io.BytesIO(self.audio)
        fmt = _detect_audio_format(self.audio)
        buffer.seek(0)
    else:
        assert isinstance(self.audio, str)
        audio = Audio.from_base64(self.audio)
        assert audio.format is not None
        fmt = audio.format.lower()

        buffer = io.BytesIO()
        sf.write(buffer, audio.audio_array, audio.sampling_rate, format=audio.format)
        # reset cursor to beginning
        buffer.seek(0)

    # OpenAI's client uses the filename extension from .name to set the Content-Type.
    buffer.name = f"audio.{fmt}"

    openai_request["file"] = buffer
    openai_request["seed"] = openai_request.pop("random_seed")
    openai_request.update(kwargs)

    # remove mistral-specific
    # TODO: revisit which fields to expose in the OpenAI format
    default_exclude = ("id", "max_tokens", "strict_audio_validation", "streaming")
    default_exclude += exclude
    for k in default_exclude:
        openai_request.pop(k, None)

    return openai_request