files.py 6.6 KB

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