local_fs_storage.py 2.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263
  1. import os
  2. import shutil
  3. from collections.abc import Generator
  4. from pathlib import Path
  5. from flask import current_app
  6. from configs import dify_config
  7. from extensions.storage.base_storage import BaseStorage
  8. class LocalFsStorage(BaseStorage):
  9. """Implementation for local filesystem storage."""
  10. def __init__(self):
  11. super().__init__()
  12. folder = dify_config.STORAGE_LOCAL_PATH
  13. if not os.path.isabs(folder):
  14. folder = os.path.join(current_app.root_path, folder)
  15. self.folder = folder
  16. def _build_filepath(self, filename: str) -> str:
  17. """Build the full file path based on the folder and filename."""
  18. if not self.folder or self.folder.endswith("/"):
  19. return self.folder + filename
  20. else:
  21. return self.folder + "/" + filename
  22. def save(self, filename, data):
  23. filepath = self._build_filepath(filename)
  24. folder = os.path.dirname(filepath)
  25. os.makedirs(folder, exist_ok=True)
  26. Path(os.path.join(os.getcwd(), filepath)).write_bytes(data)
  27. def load_once(self, filename: str) -> bytes:
  28. filepath = self._build_filepath(filename)
  29. if not os.path.exists(filepath):
  30. raise FileNotFoundError("File not found")
  31. return Path(filepath).read_bytes()
  32. def load_stream(self, filename: str) -> Generator:
  33. filepath = self._build_filepath(filename)
  34. if not os.path.exists(filepath):
  35. raise FileNotFoundError("File not found")
  36. with open(filepath, "rb") as f:
  37. while chunk := f.read(4096): # Read in chunks of 4KB
  38. yield chunk
  39. def download(self, filename, target_filepath):
  40. filepath = self._build_filepath(filename)
  41. if not os.path.exists(filepath):
  42. raise FileNotFoundError("File not found")
  43. shutil.copyfile(filepath, target_filepath)
  44. def exists(self, filename):
  45. filepath = self._build_filepath(filename)
  46. return os.path.exists(filepath)
  47. def delete(self, filename):
  48. filepath = self._build_filepath(filename)
  49. if os.path.exists(filepath):
  50. os.remove(filepath)