| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143 | 
							- from collections.abc import Mapping, Sequence
 
- from typing import Any, Optional
 
- from pydantic import BaseModel, Field, model_validator
 
- from core.model_runtime.entities.message_entities import ImagePromptMessageContent
 
- from . import helpers
 
- from .constants import FILE_MODEL_IDENTITY
 
- from .enums import FileTransferMethod, FileType
 
- from .tool_file_parser import ToolFileParser
 
- class ImageConfig(BaseModel):
 
-     """
 
-     NOTE: This part of validation is deprecated, but still used in app features "Image Upload".
 
-     """
 
-     number_limits: int = 0
 
-     transfer_methods: Sequence[FileTransferMethod] = Field(default_factory=list)
 
-     detail: ImagePromptMessageContent.DETAIL | None = None
 
- class FileUploadConfig(BaseModel):
 
-     """
 
-     File Upload Entity.
 
-     """
 
-     image_config: Optional[ImageConfig] = None
 
-     allowed_file_types: Sequence[FileType] = Field(default_factory=list)
 
-     allowed_file_extensions: Sequence[str] = Field(default_factory=list)
 
-     allowed_file_upload_methods: Sequence[FileTransferMethod] = Field(default_factory=list)
 
-     number_limits: int = 0
 
- class File(BaseModel):
 
-     dify_model_identity: str = FILE_MODEL_IDENTITY
 
-     id: Optional[str] = None  # message file id
 
-     tenant_id: str
 
-     type: FileType
 
-     transfer_method: FileTransferMethod
 
-     remote_url: Optional[str] = None  # remote url
 
-     related_id: Optional[str] = None
 
-     filename: Optional[str] = None
 
-     extension: Optional[str] = Field(default=None, description="File extension, should contains dot")
 
-     mime_type: Optional[str] = None
 
-     size: int = -1
 
-     # Those properties are private, should not be exposed to the outside.
 
-     _storage_key: str
 
-     def __init__(
 
-         self,
 
-         *,
 
-         id: Optional[str] = None,
 
-         tenant_id: str,
 
-         type: FileType,
 
-         transfer_method: FileTransferMethod,
 
-         remote_url: Optional[str] = None,
 
-         related_id: Optional[str] = None,
 
-         filename: Optional[str] = None,
 
-         extension: Optional[str] = None,
 
-         mime_type: Optional[str] = None,
 
-         size: int = -1,
 
-         storage_key: Optional[str] = None,
 
-         dify_model_identity: Optional[str] = FILE_MODEL_IDENTITY,
 
-         url: Optional[str] = None,
 
-     ):
 
-         super().__init__(
 
-             id=id,
 
-             tenant_id=tenant_id,
 
-             type=type,
 
-             transfer_method=transfer_method,
 
-             remote_url=remote_url,
 
-             related_id=related_id,
 
-             filename=filename,
 
-             extension=extension,
 
-             mime_type=mime_type,
 
-             size=size,
 
-             dify_model_identity=dify_model_identity,
 
-             url=url,
 
-         )
 
-         self._storage_key = str(storage_key)
 
-     def to_dict(self) -> Mapping[str, str | int | None]:
 
-         data = self.model_dump(mode="json")
 
-         return {
 
-             **data,
 
-             "url": self.generate_url(),
 
-         }
 
-     @property
 
-     def markdown(self) -> str:
 
-         url = self.generate_url()
 
-         if self.type == FileType.IMAGE:
 
-             text = f""
 
-         else:
 
-             text = f"[{self.filename or url}]({url})"
 
-         return text
 
-     def generate_url(self) -> Optional[str]:
 
-         if self.transfer_method == FileTransferMethod.REMOTE_URL:
 
-             return self.remote_url
 
-         elif self.transfer_method == FileTransferMethod.LOCAL_FILE:
 
-             if self.related_id is None:
 
-                 raise ValueError("Missing file related_id")
 
-             return helpers.get_signed_file_url(upload_file_id=self.related_id)
 
-         elif self.transfer_method == FileTransferMethod.TOOL_FILE:
 
-             assert self.related_id is not None
 
-             assert self.extension is not None
 
-             return ToolFileParser.get_tool_file_manager().sign_file(
 
-                 tool_file_id=self.related_id, extension=self.extension
 
-             )
 
-     def to_plugin_parameter(self) -> dict[str, Any]:
 
-         return {
 
-             "dify_model_identity": FILE_MODEL_IDENTITY,
 
-             "mime_type": self.mime_type,
 
-             "filename": self.filename,
 
-             "extension": self.extension,
 
-             "size": self.size,
 
-             "type": self.type,
 
-             "url": self.generate_url(),
 
-         }
 
-     @model_validator(mode="after")
 
-     def validate_after(self):
 
-         match self.transfer_method:
 
-             case FileTransferMethod.REMOTE_URL:
 
-                 if not self.remote_url:
 
-                     raise ValueError("Missing file url")
 
-                 if not isinstance(self.remote_url, str) or not self.remote_url.startswith("http"):
 
-                     raise ValueError("Invalid file url")
 
-             case FileTransferMethod.LOCAL_FILE:
 
-                 if not self.related_id:
 
-                     raise ValueError("Missing file related_id")
 
-             case FileTransferMethod.TOOL_FILE:
 
-                 if not self.related_id:
 
-                     raise ValueError("Missing file related_id")
 
-         return self
 
 
  |