### What problem does this PR solve? #2834 ### Type of change - [x] New Feature (non-breaking change which adds functionality)tags/v0.13.0
| self.check_positive_integer(self.port, "IP Port") | self.check_positive_integer(self.port, "IP Port") | ||||
| self.check_empty(self.password, "Database password") | self.check_empty(self.password, "Database password") | ||||
| self.check_positive_integer(self.top_n, "Number of records") | self.check_positive_integer(self.top_n, "Number of records") | ||||
| if self.database == "rag_flow": | |||||
| if self.host == "ragflow-mysql": raise ValueError("The host is not accessible.") | |||||
| if self.password == "infini_rag_flow": raise ValueError("The host is not accessible.") | |||||
| class ExeSQL(ComponentBase, ABC): | class ExeSQL(ComponentBase, ABC): |
| @manager.route('/infos', methods=['POST']) | @manager.route('/infos', methods=['POST']) | ||||
| @login_required | |||||
| def docinfos(): | def docinfos(): | ||||
| req = request.json | req = request.json | ||||
| doc_ids = req["doc_ids"] | doc_ids = req["doc_ids"] | ||||
| for doc_id in doc_ids: | |||||
| if not DocumentService.accessible(doc_id, current_user.id): | |||||
| return get_json_result( | |||||
| data=False, | |||||
| retmsg='No authorization.', | |||||
| retcode=RetCode.AUTHENTICATION_ERROR | |||||
| ) | |||||
| docs = DocumentService.get_by_ids(doc_ids) | docs = DocumentService.get_by_ids(doc_ids) | ||||
| return get_json_result(data=list(docs.dicts())) | return get_json_result(data=list(docs.dicts())) | ||||
| def change_status(): | def change_status(): | ||||
| req = request.json | req = request.json | ||||
| if str(req["status"]) not in ["0", "1"]: | if str(req["status"]) not in ["0", "1"]: | ||||
| get_json_result( | |||||
| return get_json_result( | |||||
| data=False, | data=False, | ||||
| retmsg='"Status" must be either 0 or 1!', | retmsg='"Status" must be either 0 or 1!', | ||||
| retcode=RetCode.ARGUMENT_ERROR) | retcode=RetCode.ARGUMENT_ERROR) | ||||
| if not DocumentService.accessible(req["doc_id"], current_user.id): | |||||
| return get_json_result( | |||||
| data=False, | |||||
| retmsg='No authorization.', | |||||
| retcode=RetCode.AUTHENTICATION_ERROR) | |||||
| try: | try: | ||||
| e, doc = DocumentService.get_by_id(req["doc_id"]) | e, doc = DocumentService.get_by_id(req["doc_id"]) | ||||
| if not e: | if not e: | ||||
| req = request.json | req = request.json | ||||
| doc_ids = req["doc_id"] | doc_ids = req["doc_id"] | ||||
| if isinstance(doc_ids, str): doc_ids = [doc_ids] | if isinstance(doc_ids, str): doc_ids = [doc_ids] | ||||
| for doc_id in doc_ids: | |||||
| if not DocumentService.accessible4deletion(doc_id, current_user.id): | |||||
| return get_json_result( | |||||
| data=False, | |||||
| retmsg='No authorization.', | |||||
| retcode=RetCode.AUTHENTICATION_ERROR | |||||
| ) | |||||
| root_folder = FileService.get_root_folder(current_user.id) | root_folder = FileService.get_root_folder(current_user.id) | ||||
| pf_id = root_folder["id"] | pf_id = root_folder["id"] | ||||
| FileService.init_knowledgebase_docs(pf_id, current_user.id) | FileService.init_knowledgebase_docs(pf_id, current_user.id) | ||||
| @validate_request("doc_ids", "run") | @validate_request("doc_ids", "run") | ||||
| def run(): | def run(): | ||||
| req = request.json | req = request.json | ||||
| for doc_id in req["doc_ids"]: | |||||
| if not DocumentService.accessible(doc_id, current_user.id): | |||||
| return get_json_result( | |||||
| data=False, | |||||
| retmsg='No authorization.', | |||||
| retcode=RetCode.AUTHENTICATION_ERROR | |||||
| ) | |||||
| try: | try: | ||||
| for id in req["doc_ids"]: | for id in req["doc_ids"]: | ||||
| info = {"run": str(req["run"]), "progress": 0} | info = {"run": str(req["run"]), "progress": 0} | ||||
| @validate_request("doc_id", "name") | @validate_request("doc_id", "name") | ||||
| def rename(): | def rename(): | ||||
| req = request.json | req = request.json | ||||
| if not DocumentService.accessible(req["doc_id"], current_user.id): | |||||
| return get_json_result( | |||||
| data=False, | |||||
| retmsg='No authorization.', | |||||
| retcode=RetCode.AUTHENTICATION_ERROR | |||||
| ) | |||||
| try: | try: | ||||
| e, doc = DocumentService.get_by_id(req["doc_id"]) | e, doc = DocumentService.get_by_id(req["doc_id"]) | ||||
| if not e: | if not e: | ||||
| @validate_request("doc_id", "parser_id") | @validate_request("doc_id", "parser_id") | ||||
| def change_parser(): | def change_parser(): | ||||
| req = request.json | req = request.json | ||||
| if not DocumentService.accessible(req["doc_id"], current_user.id): | |||||
| return get_json_result( | |||||
| data=False, | |||||
| retmsg='No authorization.', | |||||
| retcode=RetCode.AUTHENTICATION_ERROR | |||||
| ) | |||||
| try: | try: | ||||
| e, doc = DocumentService.get_by_id(req["doc_id"]) | e, doc = DocumentService.get_by_id(req["doc_id"]) | ||||
| if not e: | if not e: |
| # See the License for the specific language governing permissions and | # See the License for the specific language governing permissions and | ||||
| # limitations under the License. | # limitations under the License. | ||||
| # | # | ||||
| from elasticsearch_dsl import Q | |||||
| from flask import request | from flask import request | ||||
| from flask_login import login_required, current_user | from flask_login import login_required, current_user | ||||
| from api.db.services.file_service import FileService | from api.db.services.file_service import FileService | ||||
| from api.db.services.user_service import TenantService, UserTenantService | from api.db.services.user_service import TenantService, UserTenantService | ||||
| from api.utils.api_utils import server_error_response, get_data_error_result, validate_request | from api.utils.api_utils import server_error_response, get_data_error_result, validate_request | ||||
| from api.utils import get_uuid, get_format_time | |||||
| from api.db import StatusEnum, UserTenantRole, FileSource | |||||
| from api.utils import get_uuid | |||||
| from api.db import StatusEnum, FileSource | |||||
| from api.db.services.knowledgebase_service import KnowledgebaseService | from api.db.services.knowledgebase_service import KnowledgebaseService | ||||
| from api.db.db_models import Knowledgebase, File | |||||
| from api.settings import stat_logger, RetCode | |||||
| from api.db.db_models import File | |||||
| from api.settings import RetCode | |||||
| from api.utils.api_utils import get_json_result | from api.utils.api_utils import get_json_result | ||||
| from rag.nlp import search | |||||
| from rag.utils.es_conn import ELASTICSEARCH | |||||
| @manager.route('/create', methods=['post']) | @manager.route('/create', methods=['post']) | ||||
| def update(): | def update(): | ||||
| req = request.json | req = request.json | ||||
| req["name"] = req["name"].strip() | req["name"] = req["name"].strip() | ||||
| if not KnowledgebaseService.accessible4deletion(req["kb_id"], current_user.id): | |||||
| return get_json_result( | |||||
| data=False, | |||||
| retmsg='No authorization.', | |||||
| retcode=RetCode.AUTHENTICATION_ERROR | |||||
| ) | |||||
| try: | try: | ||||
| if not KnowledgebaseService.query( | if not KnowledgebaseService.query( | ||||
| created_by=current_user.id, id=req["kb_id"]): | created_by=current_user.id, id=req["kb_id"]): | ||||
| @validate_request("kb_id") | @validate_request("kb_id") | ||||
| def rm(): | def rm(): | ||||
| req = request.json | req = request.json | ||||
| if not KnowledgebaseService.accessible4deletion(req["kb_id"], current_user.id): | |||||
| return get_json_result( | |||||
| data=False, | |||||
| retmsg='No authorization.', | |||||
| retcode=RetCode.AUTHENTICATION_ERROR | |||||
| ) | |||||
| try: | try: | ||||
| kbs = KnowledgebaseService.query( | kbs = KnowledgebaseService.query( | ||||
| created_by=current_user.id, id=req["kb_id"]) | created_by=current_user.id, id=req["kb_id"]) |
| from rag.nlp import search, rag_tokenizer | from rag.nlp import search, rag_tokenizer | ||||
| from api.db import FileType, TaskStatus, ParserType, LLMType | from api.db import FileType, TaskStatus, ParserType, LLMType | ||||
| from api.db.db_models import DB, Knowledgebase, Tenant, Task | |||||
| from api.db.db_models import DB, Knowledgebase, Tenant, Task, UserTenant | |||||
| from api.db.db_models import Document | from api.db.db_models import Document | ||||
| from api.db.services.common_service import CommonService | from api.db.services.common_service import CommonService | ||||
| from api.db.services.knowledgebase_service import KnowledgebaseService | from api.db.services.knowledgebase_service import KnowledgebaseService | ||||
| return | return | ||||
| return docs[0]["tenant_id"] | return docs[0]["tenant_id"] | ||||
| @classmethod | |||||
| @DB.connection_context() | |||||
| def accessible(cls, doc_id, user_id): | |||||
| docs = cls.model.select( | |||||
| cls.model.id).join( | |||||
| Knowledgebase, on=( | |||||
| Knowledgebase.id == cls.model.kb_id) | |||||
| ).join(UserTenant, on=(UserTenant.tenant_id == Knowledgebase.tenant_id) | |||||
| ).where(cls.model.id == doc_id, UserTenant.user_id == user_id).paginate(0, 1) | |||||
| docs = docs.dicts() | |||||
| if not docs: | |||||
| return False | |||||
| return True | |||||
| @classmethod | |||||
| @DB.connection_context() | |||||
| def accessible4deletion(cls, doc_id, user_id): | |||||
| docs = cls.model.select( | |||||
| cls.model.id).join( | |||||
| Knowledgebase, on=( | |||||
| Knowledgebase.id == cls.model.kb_id) | |||||
| ).where(cls.model.id == doc_id, Knowledgebase.created_by == user_id).paginate(0, 1) | |||||
| docs = docs.dicts() | |||||
| if not docs: | |||||
| return False | |||||
| return True | |||||
| @classmethod | @classmethod | ||||
| @DB.connection_context() | @DB.connection_context() | ||||
| def get_embd_id(cls, doc_id): | def get_embd_id(cls, doc_id): |
| # limitations under the License. | # limitations under the License. | ||||
| # | # | ||||
| from api.db import StatusEnum, TenantPermission | from api.db import StatusEnum, TenantPermission | ||||
| from api.db.db_models import Knowledgebase, DB, Tenant, User | |||||
| from api.db.db_models import Knowledgebase, DB, Tenant, User, UserTenant | |||||
| from api.db.services.common_service import CommonService | from api.db.services.common_service import CommonService | ||||
| kbs = kbs.paginate(page_number, items_per_page) | kbs = kbs.paginate(page_number, items_per_page) | ||||
| return list(kbs.dicts()) | return list(kbs.dicts()) | ||||
| @classmethod | |||||
| @DB.connection_context() | |||||
| def accessible(cls, kb_id, user_id): | |||||
| docs = cls.model.select( | |||||
| cls.model.id).join(UserTenant, on=(UserTenant.tenant_id == Knowledgebase.tenant_id) | |||||
| ).where(cls.model.id == kb_id, UserTenant.user_id == user_id).paginate(0, 1) | |||||
| docs = docs.dicts() | |||||
| if not docs: | |||||
| return False | |||||
| return True | |||||
| @classmethod | |||||
| @DB.connection_context() | |||||
| def accessible4deletion(cls, kb_id, user_id): | |||||
| docs = cls.model.select( | |||||
| cls.model.id).where(cls.model.id == kb_id, cls.model.created_by == user_id).paginate(0, 1) | |||||
| docs = docs.dicts() | |||||
| if not docs: | |||||
| return False | |||||
| return True | |||||
| # limitations under the License. | # limitations under the License. | ||||
| # | # | ||||
| import os | import os | ||||
| from datetime import date | |||||
| from enum import IntEnum, Enum | from enum import IntEnum, Enum | ||||
| from api.utils.file_utils import get_project_base_directory | from api.utils.file_utils import get_project_base_directory | ||||
| from api.utils.log_utils import LoggerFactory, getLogger | from api.utils.log_utils import LoggerFactory, getLogger | ||||
| SECRET_KEY = get_base_config( | SECRET_KEY = get_base_config( | ||||
| RAG_FLOW_SERVICE_NAME, | RAG_FLOW_SERVICE_NAME, | ||||
| {}).get( | |||||
| "secret_key", | |||||
| "infiniflow") | |||||
| {}).get("secret_key", str(date.today())) | |||||
| TOKEN_EXPIRE_IN = get_base_config( | TOKEN_EXPIRE_IN = get_base_config( | ||||
| RAG_FLOW_SERVICE_NAME, {}).get( | RAG_FLOW_SERVICE_NAME, {}).get( | ||||
| "token_expires_in", 3600) | "token_expires_in", 3600) |