files.py 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218
  1. import logging
  2. import os
  3. import shutil
  4. import uuid
  5. from pathlib import Path
  6. from typing import Optional
  7. from open_webui.apps.webui.models.files import FileForm, FileModel, Files
  8. from open_webui.config import UPLOAD_DIR
  9. from open_webui.constants import ERROR_MESSAGES
  10. from open_webui.env import SRC_LOG_LEVELS
  11. from fastapi import APIRouter, Depends, File, HTTPException, UploadFile, status
  12. from fastapi.responses import FileResponse
  13. from open_webui.utils.utils import get_admin_user, get_verified_user
  14. log = logging.getLogger(__name__)
  15. log.setLevel(SRC_LOG_LEVELS["MODELS"])
  16. router = APIRouter()
  17. ############################
  18. # Upload File
  19. ############################
  20. @router.post("/")
  21. def upload_file(file: UploadFile = File(...), user=Depends(get_verified_user)):
  22. log.info(f"file.content_type: {file.content_type}")
  23. try:
  24. unsanitized_filename = file.filename
  25. filename = os.path.basename(unsanitized_filename)
  26. # replace filename with uuid
  27. id = str(uuid.uuid4())
  28. name = filename
  29. filename = f"{id}_{filename}"
  30. file_path = f"{UPLOAD_DIR}/{filename}"
  31. contents = file.file.read()
  32. with open(file_path, "wb") as f:
  33. f.write(contents)
  34. f.close()
  35. file = Files.insert_new_file(
  36. user.id,
  37. FileForm(
  38. **{
  39. "id": id,
  40. "filename": filename,
  41. "meta": {
  42. "name": name,
  43. "content_type": file.content_type,
  44. "size": len(contents),
  45. "path": file_path,
  46. },
  47. }
  48. ),
  49. )
  50. if file:
  51. return file
  52. else:
  53. raise HTTPException(
  54. status_code=status.HTTP_400_BAD_REQUEST,
  55. detail=ERROR_MESSAGES.DEFAULT("Error uploading file"),
  56. )
  57. except Exception as e:
  58. log.exception(e)
  59. raise HTTPException(
  60. status_code=status.HTTP_400_BAD_REQUEST,
  61. detail=ERROR_MESSAGES.DEFAULT(e),
  62. )
  63. ############################
  64. # List Files
  65. ############################
  66. @router.get("/", response_model=list[FileModel])
  67. async def list_files(user=Depends(get_verified_user)):
  68. if user.role == "admin":
  69. files = Files.get_files()
  70. else:
  71. files = Files.get_files_by_user_id(user.id)
  72. return files
  73. ############################
  74. # Delete All Files
  75. ############################
  76. @router.delete("/all")
  77. async def delete_all_files(user=Depends(get_admin_user)):
  78. result = Files.delete_all_files()
  79. if result:
  80. folder = f"{UPLOAD_DIR}"
  81. try:
  82. # Check if the directory exists
  83. if os.path.exists(folder):
  84. # Iterate over all the files and directories in the specified directory
  85. for filename in os.listdir(folder):
  86. file_path = os.path.join(folder, filename)
  87. try:
  88. if os.path.isfile(file_path) or os.path.islink(file_path):
  89. os.unlink(file_path) # Remove the file or link
  90. elif os.path.isdir(file_path):
  91. shutil.rmtree(file_path) # Remove the directory
  92. except Exception as e:
  93. print(f"Failed to delete {file_path}. Reason: {e}")
  94. else:
  95. print(f"The directory {folder} does not exist")
  96. except Exception as e:
  97. print(f"Failed to process the directory {folder}. Reason: {e}")
  98. return {"message": "All files deleted successfully"}
  99. else:
  100. raise HTTPException(
  101. status_code=status.HTTP_400_BAD_REQUEST,
  102. detail=ERROR_MESSAGES.DEFAULT("Error deleting files"),
  103. )
  104. ############################
  105. # Get File By Id
  106. ############################
  107. @router.get("/{id}", response_model=Optional[FileModel])
  108. async def get_file_by_id(id: str, user=Depends(get_verified_user)):
  109. file = Files.get_file_by_id(id)
  110. if file and (file.user_id == user.id or user.role == "admin"):
  111. return file
  112. else:
  113. raise HTTPException(
  114. status_code=status.HTTP_404_NOT_FOUND,
  115. detail=ERROR_MESSAGES.NOT_FOUND,
  116. )
  117. ############################
  118. # Get File Content By Id
  119. ############################
  120. @router.get("/{id}/content", response_model=Optional[FileModel])
  121. async def get_file_content_by_id(id: str, user=Depends(get_verified_user)):
  122. file = Files.get_file_by_id(id)
  123. if file and (file.user_id == user.id or user.role == "admin"):
  124. file_path = Path(file.meta["path"])
  125. # Check if the file already exists in the cache
  126. if file_path.is_file():
  127. print(f"file_path: {file_path}")
  128. return FileResponse(file_path)
  129. else:
  130. raise HTTPException(
  131. status_code=status.HTTP_404_NOT_FOUND,
  132. detail=ERROR_MESSAGES.NOT_FOUND,
  133. )
  134. else:
  135. raise HTTPException(
  136. status_code=status.HTTP_404_NOT_FOUND,
  137. detail=ERROR_MESSAGES.NOT_FOUND,
  138. )
  139. @router.get("/{id}/content/{file_name}", response_model=Optional[FileModel])
  140. async def get_file_content_by_id(id: str, user=Depends(get_verified_user)):
  141. file = Files.get_file_by_id(id)
  142. if file and (file.user_id == user.id or user.role == "admin"):
  143. file_path = Path(file.meta["path"])
  144. # Check if the file already exists in the cache
  145. if file_path.is_file():
  146. print(f"file_path: {file_path}")
  147. return FileResponse(file_path)
  148. else:
  149. raise HTTPException(
  150. status_code=status.HTTP_404_NOT_FOUND,
  151. detail=ERROR_MESSAGES.NOT_FOUND,
  152. )
  153. else:
  154. raise HTTPException(
  155. status_code=status.HTTP_404_NOT_FOUND,
  156. detail=ERROR_MESSAGES.NOT_FOUND,
  157. )
  158. ############################
  159. # Delete File By Id
  160. ############################
  161. @router.delete("/{id}")
  162. async def delete_file_by_id(id: str, user=Depends(get_verified_user)):
  163. file = Files.get_file_by_id(id)
  164. if file and (file.user_id == user.id or user.role == "admin"):
  165. result = Files.delete_file_by_id(id)
  166. if result:
  167. return {"message": "File deleted successfully"}
  168. else:
  169. raise HTTPException(
  170. status_code=status.HTTP_400_BAD_REQUEST,
  171. detail=ERROR_MESSAGES.DEFAULT("Error deleting file"),
  172. )
  173. else:
  174. raise HTTPException(
  175. status_code=status.HTTP_404_NOT_FOUND,
  176. detail=ERROR_MESSAGES.NOT_FOUND,
  177. )