mirror of
https://github.com/langgenius/dify.git
synced 2026-05-09 21:28:25 +08:00
Add an optional S3_PUBLIC_BASE_URL setting that, when configured, lets file controllers 302-redirect signed previews to the object store / CDN instead of streaming bytes through the Dify API. Works with any S3-compatible backend exposing a public domain (Cloudflare R2 custom domain, MinIO public endpoint, Aliyun OSS public domain, etc.) so that egress and request handling for images, attachments, tool outputs, and webapp logos no longer go through the API container. Signature verification is preserved: the API still validates the HMAC before issuing the redirect. When S3_PUBLIC_BASE_URL is unset the behavior is unchanged. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
52 lines
1.7 KiB
Python
52 lines
1.7 KiB
Python
"""Abstract interface for file storage implementations."""
|
|
|
|
from abc import ABC, abstractmethod
|
|
from collections.abc import Generator
|
|
|
|
|
|
class BaseStorage(ABC):
|
|
"""Interface for file storage."""
|
|
|
|
@abstractmethod
|
|
def save(self, filename: str, data: bytes):
|
|
raise NotImplementedError
|
|
|
|
@abstractmethod
|
|
def load_once(self, filename: str) -> bytes:
|
|
raise NotImplementedError
|
|
|
|
@abstractmethod
|
|
def load_stream(self, filename: str) -> Generator:
|
|
raise NotImplementedError
|
|
|
|
@abstractmethod
|
|
def download(self, filename: str, target_filepath: str) -> None:
|
|
raise NotImplementedError
|
|
|
|
@abstractmethod
|
|
def exists(self, filename: str) -> bool:
|
|
raise NotImplementedError
|
|
|
|
@abstractmethod
|
|
def delete(self, filename: str):
|
|
raise NotImplementedError
|
|
|
|
def get_public_url(self, filename: str) -> str | None:
|
|
"""
|
|
Return a publicly accessible URL for the given object, or None if the
|
|
backend is not configured to serve content publicly.
|
|
|
|
When set, file controllers will 302-redirect signed preview requests to
|
|
this URL after verifying the signature, so that the bytes themselves are
|
|
served by the object store / CDN instead of streamed through Dify's API.
|
|
"""
|
|
return None
|
|
|
|
def scan(self, path, files=True, directories=False) -> list[str]:
|
|
"""
|
|
Scan files and directories in the given path.
|
|
This method is implemented only in some storage backends.
|
|
If a storage backend doesn't support scanning, it will raise NotImplementedError.
|
|
"""
|
|
raise NotImplementedError("This storage backend doesn't support scanning")
|