Files
dify/api/core/workflow/file_reference.py
-LAN- 56593f20b0 refactor(api): continue decoupling dify_graph from API concerns (#33580)
Signed-off-by: -LAN- <laipz8200@outlook.com>
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
Co-authored-by: WH-2099 <wh2099@pm.me>
2026-03-25 20:32:24 +08:00

53 lines
1.6 KiB
Python

from __future__ import annotations
import base64
import json
from dataclasses import dataclass
_FILE_REFERENCE_PREFIX = "dify-file-ref:"
@dataclass(frozen=True)
class FileReference:
record_id: str
storage_key: str | None = None
def build_file_reference(*, record_id: str, storage_key: str | None = None) -> str:
payload = {"record_id": record_id}
if storage_key is not None:
payload["storage_key"] = storage_key
encoded_payload = base64.urlsafe_b64encode(json.dumps(payload, separators=(",", ":")).encode()).decode()
return f"{_FILE_REFERENCE_PREFIX}{encoded_payload}"
def parse_file_reference(reference: str | None) -> FileReference | None:
if not reference:
return None
if not reference.startswith(_FILE_REFERENCE_PREFIX):
return FileReference(record_id=reference)
encoded_payload = reference.removeprefix(_FILE_REFERENCE_PREFIX)
try:
payload = json.loads(base64.urlsafe_b64decode(encoded_payload.encode()))
except (ValueError, json.JSONDecodeError):
return FileReference(record_id=reference)
record_id = payload.get("record_id")
if not isinstance(record_id, str) or not record_id:
return FileReference(record_id=reference)
storage_key = payload.get("storage_key")
if storage_key is not None and not isinstance(storage_key, str):
storage_key = None
return FileReference(record_id=record_id, storage_key=storage_key)
def resolve_file_record_id(reference: str | None) -> str | None:
parsed_reference = parse_file_reference(reference)
if parsed_reference is None:
return None
return parsed_reference.record_id