files.py 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231
  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/text")
  140. async def get_file_text_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. return {"text": file.meta.get("content", {}).get("text", None)}
  144. else:
  145. raise HTTPException(
  146. status_code=status.HTTP_404_NOT_FOUND,
  147. detail=ERROR_MESSAGES.NOT_FOUND,
  148. )
  149. @router.get("/{id}/content/{file_name}", response_model=Optional[FileModel])
  150. async def get_file_content_by_id(id: str, user=Depends(get_verified_user)):
  151. file = Files.get_file_by_id(id)
  152. if file and (file.user_id == user.id or user.role == "admin"):
  153. file_path = Path(file.meta["path"])
  154. # Check if the file already exists in the cache
  155. if file_path.is_file():
  156. print(f"file_path: {file_path}")
  157. return FileResponse(file_path)
  158. else:
  159. raise HTTPException(
  160. status_code=status.HTTP_404_NOT_FOUND,
  161. detail=ERROR_MESSAGES.NOT_FOUND,
  162. )
  163. else:
  164. raise HTTPException(
  165. status_code=status.HTTP_404_NOT_FOUND,
  166. detail=ERROR_MESSAGES.NOT_FOUND,
  167. )
  168. ############################
  169. # Delete File By Id
  170. ############################
  171. @router.delete("/{id}")
  172. async def delete_file_by_id(id: str, user=Depends(get_verified_user)):
  173. file = Files.get_file_by_id(id)
  174. if file and (file.user_id == user.id or user.role == "admin"):
  175. result = Files.delete_file_by_id(id)
  176. if result:
  177. return {"message": "File deleted successfully"}
  178. else:
  179. raise HTTPException(
  180. status_code=status.HTTP_400_BAD_REQUEST,
  181. detail=ERROR_MESSAGES.DEFAULT("Error deleting file"),
  182. )
  183. else:
  184. raise HTTPException(
  185. status_code=status.HTTP_404_NOT_FOUND,
  186. detail=ERROR_MESSAGES.NOT_FOUND,
  187. )