main
py 65 lines 1.96 KB
Raw
1 # SPDX-License-Identifier: Apache-2.0
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3 """Shared utilities for speech-to-text API routes."""
4
5 from fastapi import UploadFile
6
7 import vllm.envs as envs
8 from vllm.exceptions import VLLMValidationError
9 from vllm.utils.mem_constants import KiB_bytes, MiB_bytes
10
11 _READ_CHUNK_SIZE = 64 * KiB_bytes
12
13
14 async def read_upload_with_limit(
15 file: UploadFile,
16 max_size_mb: float | None = None,
17 ) -> bytes:
18 """Read an uploaded file enforcing a size limit *before* full
19 materialization.
20
21 The function first checks the Content-Length header (``file.size``) when
22 available. Regardless, it then performs a chunked read that stops as soon
23 as the accumulated bytes exceed the limit, ensuring that an oversized
24 upload never fully materializes in memory.
25
26 Args:
27 file: The FastAPI/Starlette ``UploadFile`` object.
28 max_size_mb: Maximum allowed compressed file size in megabytes.
29 Defaults to ``envs.VLLM_MAX_AUDIO_CLIP_FILESIZE_MB``.
30
31 Returns:
32 The file content as ``bytes``.
33
34 Raises:
35 VLLMValidationError: If the file exceeds the configured size limit.
36
37 """
38 if max_size_mb is None:
39 max_size_mb = envs.VLLM_MAX_AUDIO_CLIP_FILESIZE_MB
40
41 max_bytes = int(max_size_mb * MiB_bytes)
42
43 if file.size is not None and file.size > max_bytes:
44 raise VLLMValidationError(
45 "Maximum file size exceeded",
46 parameter="audio_filesize_mb",
47 value=file.size / MiB_bytes,
48 )
49
50 chunks: list[bytes] = []
51 total = 0
52 while True:
53 chunk = await file.read(_READ_CHUNK_SIZE)
54 if not chunk:
55 break
56 total += len(chunk)
57 if total > max_bytes:
58 raise VLLMValidationError(
59 "Maximum file size exceeded",
60 parameter="audio_filesize_mb",
61 value=total / MiB_bytes,
62 )
63 chunks.append(chunk)
64
65 return b"".join(chunks)