diff --git a/api/controllers/service_api/dataset/rag_pipeline/rag_pipeline_workflow.py b/api/controllers/service_api/dataset/rag_pipeline/rag_pipeline_workflow.py index 94cbee1f58..13784b2f22 100644 --- a/api/controllers/service_api/dataset/rag_pipeline/rag_pipeline_workflow.py +++ b/api/controllers/service_api/dataset/rag_pipeline/rag_pipeline_workflow.py @@ -10,6 +10,7 @@ from controllers.common.errors import FilenameNotExistsError, NoFileUploadedErro from controllers.common.schema import register_schema_model from controllers.service_api import service_api_ns from controllers.service_api.dataset.error import PipelineRunError +from controllers.service_api.dataset.rag_pipeline.serializers import serialize_upload_file from controllers.service_api.wraps import DatasetApiResource from core.app.apps.pipeline.pipeline_generator import PipelineGenerator from core.app.entities.app_invoke_entities import InvokeFrom @@ -230,12 +231,4 @@ class KnowledgebasePipelineFileUploadApi(DatasetApiResource): except services.errors.file.UnsupportedFileTypeError: raise UnsupportedFileTypeError() - return { - "id": upload_file.id, - "name": upload_file.name, - "size": upload_file.size, - "extension": upload_file.extension, - "mime_type": upload_file.mime_type, - "created_by": upload_file.created_by, - "created_at": upload_file.created_at, - }, 201 + return serialize_upload_file(upload_file), 201 diff --git a/api/controllers/service_api/dataset/rag_pipeline/serializers.py b/api/controllers/service_api/dataset/rag_pipeline/serializers.py new file mode 100644 index 0000000000..8533c9c01d --- /dev/null +++ b/api/controllers/service_api/dataset/rag_pipeline/serializers.py @@ -0,0 +1,22 @@ +""" +Serialization helpers for Service API knowledge pipeline endpoints. +""" + +from __future__ import annotations + +from typing import TYPE_CHECKING, Any + +if TYPE_CHECKING: + from models.model import UploadFile + + +def serialize_upload_file(upload_file: UploadFile) -> dict[str, Any]: + return { + "id": upload_file.id, + "name": upload_file.name, + "size": upload_file.size, + "extension": upload_file.extension, + "mime_type": upload_file.mime_type, + "created_by": upload_file.created_by, + "created_at": upload_file.created_at.isoformat() if upload_file.created_at else None, + } diff --git a/api/tests/unit_tests/controllers/service_api/dataset/test_rag_pipeline_file_upload_serialization.py b/api/tests/unit_tests/controllers/service_api/dataset/test_rag_pipeline_file_upload_serialization.py new file mode 100644 index 0000000000..a8dd8523ac --- /dev/null +++ b/api/tests/unit_tests/controllers/service_api/dataset/test_rag_pipeline_file_upload_serialization.py @@ -0,0 +1,62 @@ +""" +Unit tests for Service API knowledge pipeline file-upload serialization. +""" + +import importlib.util +from datetime import UTC, datetime +from pathlib import Path + + +class FakeUploadFile: + id: str + name: str + size: int + extension: str + mime_type: str + created_by: str + created_at: datetime | None + + +def _load_serialize_upload_file(): + api_dir = Path(__file__).resolve().parents[5] + serializers_path = api_dir / "controllers" / "service_api" / "dataset" / "rag_pipeline" / "serializers.py" + + spec = importlib.util.spec_from_file_location("rag_pipeline_serializers", serializers_path) + assert spec + assert spec.loader + module = importlib.util.module_from_spec(spec) + spec.loader.exec_module(module) # type: ignore[attr-defined] + return module.serialize_upload_file + + +def test_file_upload_created_at_is_isoformat_string(): + serialize_upload_file = _load_serialize_upload_file() + + created_at = datetime(2026, 2, 8, 12, 0, 0, tzinfo=UTC) + upload_file = FakeUploadFile() + upload_file.id = "file-1" + upload_file.name = "test.pdf" + upload_file.size = 123 + upload_file.extension = "pdf" + upload_file.mime_type = "application/pdf" + upload_file.created_by = "account-1" + upload_file.created_at = created_at + + result = serialize_upload_file(upload_file) + assert result["created_at"] == created_at.isoformat() + + +def test_file_upload_created_at_none_serializes_to_null(): + serialize_upload_file = _load_serialize_upload_file() + + upload_file = FakeUploadFile() + upload_file.id = "file-1" + upload_file.name = "test.pdf" + upload_file.size = 123 + upload_file.extension = "pdf" + upload_file.mime_type = "application/pdf" + upload_file.created_by = "account-1" + upload_file.created_at = None + + result = serialize_upload_file(upload_file) + assert result["created_at"] is None