[BugFix] Add field validators for /v1/audio/generate request (#4741)
Signed-off-by: Shaun Walsh <shaunwalsh24@gmail.com> Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> Co-authored-by: Nick Cao <ncao@redhat.com>
This commit is contained in:
2 files changed
+27
-19
No files matched your search
@@ -13,9 +13,6 @@ from tests.helpers.runtime import OmniServer, OmniServerParams, OnlineOmniClient
|
||||
|
||||
pytestmark = [pytest.mark.slow, pytest.mark.diffusion]
|
||||
|
||||
# https://github.com/vllm-project/vllm-omni/issues/3649 — invalid inputs still HTTP 200 / timeout / missing validation.
|
||||
_SKIP_ISSUE_3649 = pytest.mark.skip(reason="https://github.com/vllm-project/vllm-omni/issues/3649")
|
||||
|
||||
_PARAMS = [
|
||||
pytest.param(
|
||||
OmniServerParams(
|
||||
@@ -36,10 +33,8 @@ _PARAMS = [
|
||||
@pytest.mark.parametrize(
|
||||
"overrides, err_message",
|
||||
[
|
||||
pytest.param({"input": ""}, ("cannot be empty", "input"), id="input_empty", marks=_SKIP_ISSUE_3649),
|
||||
pytest.param(
|
||||
{"input": " "}, ("cannot be empty", "input"), id="input_whitespace_only", marks=_SKIP_ISSUE_3649
|
||||
),
|
||||
pytest.param({"input": ""}, ("cannot be empty", "input"), id="input_empty"),
|
||||
pytest.param({"input": " "}, ("cannot be empty", "input"), id="input_whitespace_only"),
|
||||
pytest.param({"input": 123}, ("input", "a valid string"), id="input_wrong_type"),
|
||||
pytest.param(
|
||||
{"response_format": "mpeg"},
|
||||
@@ -54,10 +49,8 @@ _PARAMS = [
|
||||
("sse", "stream_format", "value_error", "not a supported stream_format"),
|
||||
id="stream_format_sse_blocked",
|
||||
),
|
||||
pytest.param(
|
||||
{"audio_length": -1.0}, ("audio_end_in_s", "higher than", "audio_start_in_s"), id="audio_length_negative"
|
||||
),
|
||||
pytest.param({"audio_length": 0}, "audio_length", id="audio_length_zero", marks=_SKIP_ISSUE_3649),
|
||||
pytest.param({"audio_length": -1.0}, ("audio_length", "greater_than", "0"), id="audio_length_negative"),
|
||||
pytest.param({"audio_length": 0}, ("audio_length", "greater_than", "0"), id="audio_length_zero"),
|
||||
# ``OmniOpenAIServingAudioGenerate`` only forwards ``audio_start`` when ``audio_length`` is set.
|
||||
pytest.param(
|
||||
{"audio_start": -0.5, "audio_length": 5.0},
|
||||
@@ -67,26 +60,30 @@ _PARAMS = [
|
||||
pytest.param(
|
||||
{"negative_prompt": ["noise"]}, ("negative_prompt", "a valid string"), id="negative_prompt_wrong_type"
|
||||
),
|
||||
pytest.param({"guidance_scale": -1.0}, "guidance_scale", id="guidance_scale_negative", marks=_SKIP_ISSUE_3649),
|
||||
pytest.param({"guidance_scale": 0}, "guidance_scale", id="guidance_scale_zero", marks=_SKIP_ISSUE_3649),
|
||||
pytest.param(
|
||||
{"guidance_scale": -1.0},
|
||||
("guidance_scale", "greater_than_equal", "0"),
|
||||
id="guidance_scale_negative",
|
||||
),
|
||||
pytest.param(
|
||||
{"num_inference_steps": 0},
|
||||
("num_inference_steps", "greater than or equal to 1"),
|
||||
("num_inference_steps", "greater_than_equal", "1"),
|
||||
id="num_inference_steps_zero",
|
||||
),
|
||||
pytest.param(
|
||||
{"num_inference_steps": -1},
|
||||
("num_inference_steps", "greater than or equal to 1"),
|
||||
("num_inference_steps", "greater_than_equal", "1"),
|
||||
id="num_inference_steps_negative",
|
||||
),
|
||||
pytest.param(
|
||||
{"num_inference_steps": 6000},
|
||||
"num_inference_steps",
|
||||
("num_inference_steps", "less_than_equal", "1000"),
|
||||
id="num_inference_steps_above_max",
|
||||
marks=_SKIP_ISSUE_3649,
|
||||
),
|
||||
pytest.param(
|
||||
{"guidance_scale": 1001.0}, "guidance_scale", id="guidance_scale_above_max", marks=_SKIP_ISSUE_3649
|
||||
{"guidance_scale": 1001.0},
|
||||
("guidance_scale", "less_than_equal", "1000"),
|
||||
id="guidance_scale_above_max",
|
||||
),
|
||||
pytest.param(
|
||||
{"audio_length": 86401.0}, ("Requested audio length", "exceeds maximum"), id="audio_length_above_max"
|
||||
|
||||
@@ -353,6 +353,14 @@ class OpenAICreateAudioGenerateRequest(BaseModel):
|
||||
input: str = Field(
|
||||
description="Text prompt describing the audio to generate",
|
||||
)
|
||||
|
||||
@field_validator("input")
|
||||
@classmethod
|
||||
def validate_input(cls, v):
|
||||
if not v or not v.strip():
|
||||
raise ValueError("input cannot be empty")
|
||||
return v
|
||||
|
||||
model: str | None = None
|
||||
response_format: Literal["wav", "pcm", "flac", "mp3", "opus"] = DEFAULT_AUDIO_FORMAT
|
||||
speed: float | None = Field(
|
||||
@@ -363,6 +371,7 @@ class OpenAICreateAudioGenerateRequest(BaseModel):
|
||||
stream_format: Literal["sse", "audio"] | None = "audio"
|
||||
audio_length: float | None = Field(
|
||||
default=None,
|
||||
gt=0,
|
||||
description="Audio length in seconds",
|
||||
)
|
||||
audio_start: float | None = Field(
|
||||
@@ -375,12 +384,14 @@ class OpenAICreateAudioGenerateRequest(BaseModel):
|
||||
)
|
||||
guidance_scale: float | None = Field(
|
||||
default=None,
|
||||
ge=0,
|
||||
le=1000,
|
||||
description="Guidance scale for diffusion models",
|
||||
)
|
||||
num_inference_steps: int | None = Field(
|
||||
default=None,
|
||||
ge=1,
|
||||
le=_INT64_MAX,
|
||||
le=1000,
|
||||
description="Number of inference steps",
|
||||
)
|
||||
seed: int | None = Field(
|
||||
|
||||
Reference in new issue
Block a user