fix(audio): derive transcription filename with os.path.basename

process_audio_file derived the multipart filename from a PathLike input
with file_path.split("/")[-1]. On Windows, str(Path('C:/dir/name.mp3'))
is 'C:\\dir\\name.mp3', which contains no forward slash, so the split
returned the entire path (drive letter and backslashes) instead of the
basename. That full path was then sent to provider transcription APIs as
the form-data file name.

Use os.path.basename, matching the sibling PathLike file-input sink in
ocr/main.py. Add a regression test that patches os.path to ntpath to
reproduce Windows semantics on any host.

Signed-off-by: Anas Khan <83116240+anxkhn@users.noreply.github.com>
This commit is contained in:
Anas Khan 2026-07-06 14:21:17 +05:30
parent 60729f733e
commit dee48d0e7b
No known key found for this signature in database
2 changed files with 30 additions and 1 deletions

View file

@ -69,7 +69,7 @@ def process_audio_file(audio_file: FileTypes) -> ProcessedAudioFile:
file_path = str(audio_file)
with open(file_path, "rb") as f:
file_content = f.read()
filename = file_path.split("/")[-1]
filename = os.path.basename(file_path)
elif isinstance(audio_file, tuple):
# Tuple format: (filename, content, content_type) or (filename, content)
if len(audio_file) >= 2:

View file

@ -69,6 +69,35 @@ class TestProcessAudioFile:
with pytest.raises(ValueError, match="does not accept bare str inputs"):
process_audio_file("/etc/passwd")
def test_process_windows_pathlib_input_basename(self):
"""A Windows path must yield only the basename, not the full drive path.
On Windows, str(Path('C:/dir/name.mp3')) is 'C:\\dir\\name.mp3', which
contains no '/'. Deriving the filename with str.split('/')[-1] would send
the entire path (drive letter and backslashes) to the provider as the
multipart file name. os.path is patched to ntpath here to reproduce
Windows semantics on any host.
"""
import ntpath
from pathlib import PureWindowsPath
windows_path = PureWindowsPath("C:/Users/me/audio recording.mp3")
test_content = b"test audio content"
with (
patch("litellm.litellm_core_utils.audio_utils.utils.os.path", ntpath),
patch(
"litellm.litellm_core_utils.audio_utils.utils.open",
mock_open(read_data=test_content),
create=True,
),
):
result = process_audio_file(windows_path)
assert result.file_content == test_content
assert result.filename == "audio recording.mp3"
assert result.content_type == "audio/mpeg"
def test_process_tuple_input_with_bytes(self):
"""Test processing tuple input with bytes content"""
filename = "test.wav"