| 
									
										
										
										
											2024-06-19 02:36:55 +08:00
										 |  |  | import logging | 
					
						
							| 
									
										
										
										
											2024-08-28 06:10:27 +08:00
										 |  |  | import time | 
					
						
							|  |  |  | from typing import Optional | 
					
						
							| 
									
										
										
										
											2024-06-18 21:03:31 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-12-10 16:54:13 +08:00
										 |  |  | from open_webui.internal.db import Base, JSONField, get_db | 
					
						
							| 
									
										
										
										
											2024-09-04 22:54:48 +08:00
										 |  |  | from open_webui.env import SRC_LOG_LEVELS | 
					
						
							| 
									
										
										
										
											2024-08-28 06:10:27 +08:00
										 |  |  | from pydantic import BaseModel, ConfigDict | 
					
						
							| 
									
										
										
										
											2024-10-02 02:01:26 +08:00
										 |  |  | from sqlalchemy import BigInteger, Column, String, Text, JSON | 
					
						
							| 
									
										
										
										
											2024-06-19 02:36:55 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | log = logging.getLogger(__name__) | 
					
						
							|  |  |  | log.setLevel(SRC_LOG_LEVELS["MODELS"]) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #################### | 
					
						
							|  |  |  | # Files DB Schema | 
					
						
							|  |  |  | #################### | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-06-18 21:03:31 +08:00
										 |  |  | class File(Base): | 
					
						
							|  |  |  |     __tablename__ = "file" | 
					
						
							|  |  |  |     id = Column(String, primary_key=True) | 
					
						
							|  |  |  |     user_id = Column(String) | 
					
						
							| 
									
										
										
										
											2024-10-03 12:14:58 +08:00
										 |  |  |     hash = Column(Text, nullable=True) | 
					
						
							| 
									
										
										
										
											2024-10-02 02:01:26 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-06-24 19:21:51 +08:00
										 |  |  |     filename = Column(Text) | 
					
						
							| 
									
										
										
										
											2024-10-21 08:45:37 +08:00
										 |  |  |     path = Column(Text, nullable=True) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-10-03 21:45:15 +08:00
										 |  |  |     data = Column(JSON, nullable=True) | 
					
						
							| 
									
										
										
										
											2024-10-21 08:45:37 +08:00
										 |  |  |     meta = Column(JSON, nullable=True) | 
					
						
							| 
									
										
										
										
											2024-10-02 02:01:26 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-12-24 05:43:58 +08:00
										 |  |  |     access_control = Column(JSON, nullable=True) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-06-18 21:03:31 +08:00
										 |  |  |     created_at = Column(BigInteger) | 
					
						
							| 
									
										
										
										
											2024-10-02 02:01:26 +08:00
										 |  |  |     updated_at = Column(BigInteger) | 
					
						
							| 
									
										
										
										
											2024-06-19 02:36:55 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | class FileModel(BaseModel): | 
					
						
							| 
									
										
										
										
											2024-10-02 02:01:26 +08:00
										 |  |  |     model_config = ConfigDict(from_attributes=True) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-06-19 02:36:55 +08:00
										 |  |  |     id: str | 
					
						
							|  |  |  |     user_id: str | 
					
						
							| 
									
										
										
										
											2024-10-03 12:14:58 +08:00
										 |  |  |     hash: Optional[str] = None | 
					
						
							| 
									
										
										
										
											2024-10-02 02:01:26 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-06-19 02:36:55 +08:00
										 |  |  |     filename: str | 
					
						
							| 
									
										
										
										
											2024-10-21 08:45:37 +08:00
										 |  |  |     path: Optional[str] = None | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-10-03 21:45:15 +08:00
										 |  |  |     data: Optional[dict] = None | 
					
						
							| 
									
										
										
										
											2024-10-21 08:45:37 +08:00
										 |  |  |     meta: Optional[dict] = None | 
					
						
							| 
									
										
										
										
											2024-06-19 02:36:55 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-12-24 05:43:58 +08:00
										 |  |  |     access_control: Optional[dict] = None | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-10-25 05:53:14 +08:00
										 |  |  |     created_at: Optional[int]  # timestamp in epoch | 
					
						
							|  |  |  |     updated_at: Optional[int]  # timestamp in epoch | 
					
						
							| 
									
										
										
										
											2024-06-19 02:36:55 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-06-24 15:57:08 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-06-19 02:36:55 +08:00
										 |  |  | #################### | 
					
						
							|  |  |  | # Forms | 
					
						
							|  |  |  | #################### | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-10-12 17:31:10 +08:00
										 |  |  | class FileMeta(BaseModel): | 
					
						
							|  |  |  |     name: Optional[str] = None | 
					
						
							|  |  |  |     content_type: Optional[str] = None | 
					
						
							|  |  |  |     size: Optional[int] = None | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     model_config = ConfigDict(extra="allow") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-06-19 05:33:44 +08:00
										 |  |  | class FileModelResponse(BaseModel): | 
					
						
							| 
									
										
										
										
											2024-06-19 02:36:55 +08:00
										 |  |  |     id: str | 
					
						
							|  |  |  |     user_id: str | 
					
						
							| 
									
										
										
										
											2024-10-03 12:14:58 +08:00
										 |  |  |     hash: Optional[str] = None | 
					
						
							| 
									
										
										
										
											2024-10-02 02:01:26 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-06-19 02:36:55 +08:00
										 |  |  |     filename: str | 
					
						
							| 
									
										
										
										
											2024-10-03 21:45:15 +08:00
										 |  |  |     data: Optional[dict] = None | 
					
						
							| 
									
										
										
										
											2024-10-12 17:31:10 +08:00
										 |  |  |     meta: FileMeta | 
					
						
							| 
									
										
										
										
											2024-10-02 02:01:26 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-06-19 02:36:55 +08:00
										 |  |  |     created_at: int  # timestamp in epoch | 
					
						
							| 
									
										
										
										
											2024-10-02 02:01:26 +08:00
										 |  |  |     updated_at: int  # timestamp in epoch | 
					
						
							| 
									
										
										
										
											2024-06-19 02:36:55 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-10-27 03:56:37 +08:00
										 |  |  |     model_config = ConfigDict(extra="allow") | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-06-19 02:36:55 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-10-12 17:31:10 +08:00
										 |  |  | class FileMetadataResponse(BaseModel): | 
					
						
							|  |  |  |     id: str | 
					
						
							|  |  |  |     meta: dict | 
					
						
							|  |  |  |     created_at: int  # timestamp in epoch | 
					
						
							|  |  |  |     updated_at: int  # timestamp in epoch | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-06-19 02:36:55 +08:00
										 |  |  | class FileForm(BaseModel): | 
					
						
							|  |  |  |     id: str | 
					
						
							| 
									
										
										
										
											2024-10-03 12:14:58 +08:00
										 |  |  |     hash: Optional[str] = None | 
					
						
							| 
									
										
										
										
											2024-06-19 02:36:55 +08:00
										 |  |  |     filename: str | 
					
						
							| 
									
										
										
										
											2024-10-21 08:45:37 +08:00
										 |  |  |     path: str | 
					
						
							| 
									
										
										
										
											2024-10-03 21:45:15 +08:00
										 |  |  |     data: dict = {} | 
					
						
							| 
									
										
										
										
											2024-06-19 02:36:55 +08:00
										 |  |  |     meta: dict = {} | 
					
						
							| 
									
										
										
										
											2024-12-24 05:43:58 +08:00
										 |  |  |     access_control: Optional[dict] = None | 
					
						
							| 
									
										
										
										
											2024-06-19 02:36:55 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | class FilesTable: | 
					
						
							| 
									
										
										
										
											2024-06-21 20:58:57 +08:00
										 |  |  |     def insert_new_file(self, user_id: str, form_data: FileForm) -> Optional[FileModel]: | 
					
						
							| 
									
										
										
										
											2024-07-04 14:32:39 +08:00
										 |  |  |         with get_db() as db: | 
					
						
							|  |  |  |             file = FileModel( | 
					
						
							|  |  |  |                 **{ | 
					
						
							|  |  |  |                     **form_data.model_dump(), | 
					
						
							|  |  |  |                     "user_id": user_id, | 
					
						
							|  |  |  |                     "created_at": int(time.time()), | 
					
						
							| 
									
										
										
										
											2024-10-02 05:00:19 +08:00
										 |  |  |                     "updated_at": int(time.time()), | 
					
						
							| 
									
										
										
										
											2024-07-04 14:32:39 +08:00
										 |  |  |                 } | 
					
						
							|  |  |  |             ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             try: | 
					
						
							|  |  |  |                 result = File(**file.model_dump()) | 
					
						
							|  |  |  |                 db.add(result) | 
					
						
							|  |  |  |                 db.commit() | 
					
						
							|  |  |  |                 db.refresh(result) | 
					
						
							|  |  |  |                 if result: | 
					
						
							|  |  |  |                     return FileModel.model_validate(result) | 
					
						
							|  |  |  |                 else: | 
					
						
							|  |  |  |                     return None | 
					
						
							|  |  |  |             except Exception as e: | 
					
						
							| 
									
										
										
										
											2025-02-25 22:36:25 +08:00
										 |  |  |                 log.exception(f"Error inserting a new file: {e}") | 
					
						
							| 
									
										
										
										
											2024-06-24 19:06:15 +08:00
										 |  |  |                 return None | 
					
						
							| 
									
										
										
										
											2024-06-19 02:36:55 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-06-21 20:58:57 +08:00
										 |  |  |     def get_file_by_id(self, id: str) -> Optional[FileModel]: | 
					
						
							| 
									
										
										
										
											2024-07-04 14:32:39 +08:00
										 |  |  |         with get_db() as db: | 
					
						
							|  |  |  |             try: | 
					
						
							|  |  |  |                 file = db.get(File, id) | 
					
						
							|  |  |  |                 return FileModel.model_validate(file) | 
					
						
							| 
									
										
										
										
											2024-08-14 20:38:19 +08:00
										 |  |  |             except Exception: | 
					
						
							| 
									
										
										
										
											2024-07-04 14:32:39 +08:00
										 |  |  |                 return None | 
					
						
							| 
									
										
										
										
											2024-06-19 02:36:55 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-10-12 17:31:10 +08:00
										 |  |  |     def get_file_metadata_by_id(self, id: str) -> Optional[FileMetadataResponse]: | 
					
						
							|  |  |  |         with get_db() as db: | 
					
						
							|  |  |  |             try: | 
					
						
							|  |  |  |                 file = db.get(File, id) | 
					
						
							|  |  |  |                 return FileMetadataResponse( | 
					
						
							|  |  |  |                     id=file.id, | 
					
						
							|  |  |  |                     meta=file.meta, | 
					
						
							|  |  |  |                     created_at=file.created_at, | 
					
						
							|  |  |  |                     updated_at=file.updated_at, | 
					
						
							|  |  |  |                 ) | 
					
						
							|  |  |  |             except Exception: | 
					
						
							|  |  |  |                 return None | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-08-14 20:46:31 +08:00
										 |  |  |     def get_files(self) -> list[FileModel]: | 
					
						
							| 
									
										
										
										
											2024-07-04 14:32:39 +08:00
										 |  |  |         with get_db() as db: | 
					
						
							|  |  |  |             return [FileModel.model_validate(file) for file in db.query(File).all()] | 
					
						
							| 
									
										
										
										
											2024-06-19 02:36:55 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-10-03 11:42:10 +08:00
										 |  |  |     def get_files_by_ids(self, ids: list[str]) -> list[FileModel]: | 
					
						
							|  |  |  |         with get_db() as db: | 
					
						
							|  |  |  |             return [ | 
					
						
							|  |  |  |                 FileModel.model_validate(file) | 
					
						
							| 
									
										
										
										
											2024-10-05 09:28:48 +08:00
										 |  |  |                 for file in db.query(File) | 
					
						
							|  |  |  |                 .filter(File.id.in_(ids)) | 
					
						
							|  |  |  |                 .order_by(File.updated_at.desc()) | 
					
						
							| 
									
										
										
										
											2024-10-12 17:31:10 +08:00
										 |  |  |                 .all() | 
					
						
							|  |  |  |             ] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def get_file_metadatas_by_ids(self, ids: list[str]) -> list[FileMetadataResponse]: | 
					
						
							|  |  |  |         with get_db() as db: | 
					
						
							|  |  |  |             return [ | 
					
						
							|  |  |  |                 FileMetadataResponse( | 
					
						
							|  |  |  |                     id=file.id, | 
					
						
							|  |  |  |                     meta=file.meta, | 
					
						
							|  |  |  |                     created_at=file.created_at, | 
					
						
							|  |  |  |                     updated_at=file.updated_at, | 
					
						
							|  |  |  |                 ) | 
					
						
							|  |  |  |                 for file in db.query(File) | 
					
						
							|  |  |  |                 .filter(File.id.in_(ids)) | 
					
						
							|  |  |  |                 .order_by(File.updated_at.desc()) | 
					
						
							| 
									
										
										
										
											2024-10-05 09:28:48 +08:00
										 |  |  |                 .all() | 
					
						
							| 
									
										
										
										
											2024-10-03 11:42:10 +08:00
										 |  |  |             ] | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-08-23 22:19:04 +08:00
										 |  |  |     def get_files_by_user_id(self, user_id: str) -> list[FileModel]: | 
					
						
							|  |  |  |         with get_db() as db: | 
					
						
							|  |  |  |             return [ | 
					
						
							|  |  |  |                 FileModel.model_validate(file) | 
					
						
							|  |  |  |                 for file in db.query(File).filter_by(user_id=user_id).all() | 
					
						
							|  |  |  |             ] | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-10-03 12:14:58 +08:00
										 |  |  |     def update_file_hash_by_id(self, id: str, hash: str) -> Optional[FileModel]: | 
					
						
							|  |  |  |         with get_db() as db: | 
					
						
							|  |  |  |             try: | 
					
						
							|  |  |  |                 file = db.query(File).filter_by(id=id).first() | 
					
						
							|  |  |  |                 file.hash = hash | 
					
						
							|  |  |  |                 db.commit() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                 return FileModel.model_validate(file) | 
					
						
							|  |  |  |             except Exception: | 
					
						
							|  |  |  |                 return None | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def update_file_data_by_id(self, id: str, data: dict) -> Optional[FileModel]: | 
					
						
							| 
									
										
										
										
											2024-10-02 04:13:39 +08:00
										 |  |  |         with get_db() as db: | 
					
						
							|  |  |  |             try: | 
					
						
							|  |  |  |                 file = db.query(File).filter_by(id=id).first() | 
					
						
							| 
									
										
										
										
											2024-10-03 21:45:15 +08:00
										 |  |  |                 file.data = {**(file.data if file.data else {}), **data} | 
					
						
							| 
									
										
										
										
											2024-10-02 04:13:39 +08:00
										 |  |  |                 db.commit() | 
					
						
							|  |  |  |                 return FileModel.model_validate(file) | 
					
						
							| 
									
										
										
										
											2024-10-03 21:45:15 +08:00
										 |  |  |             except Exception as e: | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-10-02 04:13:39 +08:00
										 |  |  |                 return None | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-10-03 12:14:58 +08:00
										 |  |  |     def update_file_metadata_by_id(self, id: str, meta: dict) -> Optional[FileModel]: | 
					
						
							| 
									
										
										
										
											2024-09-28 08:56:56 +08:00
										 |  |  |         with get_db() as db: | 
					
						
							|  |  |  |             try: | 
					
						
							|  |  |  |                 file = db.query(File).filter_by(id=id).first() | 
					
						
							| 
									
										
										
										
											2024-10-03 21:45:15 +08:00
										 |  |  |                 file.meta = {**(file.meta if file.meta else {}), **meta} | 
					
						
							| 
									
										
										
										
											2024-09-28 08:56:56 +08:00
										 |  |  |                 db.commit() | 
					
						
							|  |  |  |                 return FileModel.model_validate(file) | 
					
						
							|  |  |  |             except Exception: | 
					
						
							|  |  |  |                 return None | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-06-21 20:58:57 +08:00
										 |  |  |     def delete_file_by_id(self, id: str) -> bool: | 
					
						
							| 
									
										
										
										
											2024-07-04 14:32:39 +08:00
										 |  |  |         with get_db() as db: | 
					
						
							|  |  |  |             try: | 
					
						
							|  |  |  |                 db.query(File).filter_by(id=id).delete() | 
					
						
							| 
									
										
										
										
											2024-07-06 23:10:58 +08:00
										 |  |  |                 db.commit() | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-07-04 14:32:39 +08:00
										 |  |  |                 return True | 
					
						
							| 
									
										
										
										
											2024-08-14 20:38:19 +08:00
										 |  |  |             except Exception: | 
					
						
							| 
									
										
										
										
											2024-07-04 14:32:39 +08:00
										 |  |  |                 return False | 
					
						
							| 
									
										
										
										
											2024-06-19 02:36:55 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-06-21 20:58:57 +08:00
										 |  |  |     def delete_all_files(self) -> bool: | 
					
						
							| 
									
										
										
										
											2024-07-04 14:32:39 +08:00
										 |  |  |         with get_db() as db: | 
					
						
							|  |  |  |             try: | 
					
						
							|  |  |  |                 db.query(File).delete() | 
					
						
							| 
									
										
										
										
											2024-07-06 23:10:58 +08:00
										 |  |  |                 db.commit() | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-07-04 14:32:39 +08:00
										 |  |  |                 return True | 
					
						
							| 
									
										
										
										
											2024-08-14 20:38:19 +08:00
										 |  |  |             except Exception: | 
					
						
							| 
									
										
										
										
											2024-07-04 14:32:39 +08:00
										 |  |  |                 return False | 
					
						
							| 
									
										
										
										
											2024-06-19 05:15:08 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-06-19 02:36:55 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-06-18 21:03:31 +08:00
										 |  |  | Files = FilesTable() |