From 74b8f1bc1c20ff3a1df7b41bdac7114fe8b5af65 Mon Sep 17 00:00:00 2001 From: VectorPeak Date: Wed, 22 Jul 2026 02:04:15 +0800 Subject: [PATCH] Fix File helper extension handling (#4531) Preserve explicit suffixes when building data-backed File resource URIs, while keeping the inferred-extension fallback for names without a suffix. Closes #4530 Co-authored-by: chatgpt-codex-connector[bot] <199175422+chatgpt-codex-connector[bot]@users.noreply.github.com> --- fastmcp_slim/fastmcp/utilities/types.py | 7 ++++++- tests/utilities/test_types.py | 16 ++++++++++++++++ 2 files changed, 22 insertions(+), 1 deletion(-) diff --git a/fastmcp_slim/fastmcp/utilities/types.py b/fastmcp_slim/fastmcp/utilities/types.py index fe43c9081..47d132e63 100644 --- a/fastmcp_slim/fastmcp/utilities/types.py +++ b/fastmcp_slim/fastmcp/utilities/types.py @@ -421,7 +421,12 @@ class File: elif self.data is not None: raw_data = self.data if self._name: - uri_str = f"file:///{self._name}.{self._mime_type.split('/')[1]}" + extension = ( + "" + if Path(self._name).suffix + else f".{self._mime_type.split('/')[1]}" + ) + uri_str = f"file:///{self._name}{extension}" else: uri_str = f"file:///resource.{self._mime_type.split('/')[1]}" else: diff --git a/tests/utilities/test_types.py b/tests/utilities/test_types.py index 3d366aa64..85aa8c2be 100644 --- a/tests/utilities/test_types.py +++ b/tests/utilities/test_types.py @@ -461,6 +461,22 @@ class TestFile: if isinstance(resource.resource, BlobResourceContents): assert resource.resource.blob == base64.b64encode(test_data).decode() + def test_to_resource_content_with_data_and_name_without_extension(self): + """Test data-backed File URI with a custom name that needs an extension.""" + file = File(data=b"test file data", format="pdf", name="report") + resource = file.to_resource_content() + + assert resource.resource.mime_type == "application/pdf" + assert str(resource.resource.uri) == "file:///report.pdf" + + def test_to_resource_content_with_data_preserves_name_extension(self): + """Test data-backed File URI preserves a custom name with an extension.""" + file = File(data=b"test file data", format="pdf", name="report.pdf") + resource = file.to_resource_content() + + assert resource.resource.mime_type == "application/pdf" + assert str(resource.resource.uri) == "file:///report.pdf" + def test_to_resource_content_with_text_data(self): """Test conversion to ResourceContent with text data (TextResourceContents).""" test_data = b"hello world"