From 9bb1260558315c03a6b772e82a6bb146efd7ca6f Mon Sep 17 00:00:00 2001 From: Praneth Paruchuri Date: Sun, 1 Feb 2026 13:14:44 +0530 Subject: [PATCH] [Feature] Support file:// URL format for multimodal inputs (#14490) Co-authored-by: Yuhao Yang <47235274+yhyang201@users.noreply.github.com> --- python/sglang/srt/utils/common.py | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/python/sglang/srt/utils/common.py b/python/sglang/srt/utils/common.py index d7ad5a96f..cb18136be 100644 --- a/python/sglang/srt/utils/common.py +++ b/python/sglang/srt/utils/common.py @@ -70,7 +70,7 @@ from typing import ( Union, ) from unittest import SkipTest -from urllib.parse import urlparse +from urllib.parse import unquote, urlparse import numpy as np import orjson @@ -860,6 +860,9 @@ def load_audio( audio_file = BytesIO(response.content) response.close() audio, original_sr = sf.read(audio_file) + elif audio_file.startswith("file://"): + audio_file = unquote(urlparse(audio_file).path) + audio, original_sr = sf.read(audio_file) elif isinstance(audio_file, str): audio, original_sr = sf.read(audio_file) else: @@ -905,6 +908,9 @@ def load_image( image.load() # Force loading to avoid issues after closing the stream finally: response.close() + elif image_file.startswith("file://"): + image_file = unquote(urlparse(image_file).path) + image = Image.open(image_file) elif image_file.lower().endswith(("png", "jpg", "jpeg", "webp", "gif")): image = Image.open(image_file) elif image_file.startswith("data:"): @@ -925,6 +931,10 @@ def get_image_bytes(image_file: Union[str, bytes]): timeout = int(os.getenv("REQUEST_TIMEOUT", "3")) response = requests.get(image_file, timeout=timeout) return response.content + elif image_file.startswith("file://"): + image_file = unquote(urlparse(image_file).path) + with open(image_file, "rb") as f: + return f.read() elif image_file.lower().endswith(("png", "jpg", "jpeg", "webp", "gif")): with open(image_file, "rb") as f: return f.read() @@ -974,8 +984,11 @@ def load_video(video_file: Union[str, bytes], use_gpu: bool = True): tmp_file.write(video_bytes) tmp_file.close() vr = VideoReader(tmp_file.name, ctx=ctx) + elif video_file.startswith("file://"): + video_file = unquote(urlparse(video_file).path) + vr = VideoReader(video_file, ctx=ctx) # `urlparse` supports file:// paths, and so does VideoReader - elif os.path.isfile(urlparse(video_file).path): + elif os.path.isfile(unquote(urlparse(video_file).path)): vr = VideoReader(video_file, ctx=ctx) else: video_bytes = pybase64.b64decode(video_file, validate=True)