segment.py 9.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218
  1. from flask_login import current_user
  2. from flask_restful import marshal, reqparse
  3. from werkzeug.exceptions import NotFound
  4. from controllers.service_api import api
  5. from controllers.service_api.app.error import ProviderNotInitializeError
  6. from controllers.service_api.wraps import (
  7. DatasetApiResource,
  8. cloud_edition_billing_knowledge_limit_check,
  9. cloud_edition_billing_resource_check,
  10. )
  11. from core.errors.error import LLMBadRequestError, ProviderTokenNotInitError
  12. from core.model_manager import ModelManager
  13. from core.model_runtime.entities.model_entities import ModelType
  14. from extensions.ext_database import db
  15. from fields.segment_fields import segment_fields
  16. from models.dataset import Dataset, DocumentSegment
  17. from services.dataset_service import DatasetService, DocumentService, SegmentService
  18. class SegmentApi(DatasetApiResource):
  19. """Resource for segments."""
  20. @cloud_edition_billing_resource_check('vector_space', 'dataset')
  21. @cloud_edition_billing_knowledge_limit_check('add_segment', 'dataset')
  22. def post(self, tenant_id, dataset_id, document_id):
  23. """Create single segment."""
  24. # check dataset
  25. dataset_id = str(dataset_id)
  26. tenant_id = str(tenant_id)
  27. dataset = db.session.query(Dataset).filter(
  28. Dataset.tenant_id == tenant_id,
  29. Dataset.id == dataset_id
  30. ).first()
  31. if not dataset:
  32. raise NotFound('Dataset not found.')
  33. # check document
  34. document_id = str(document_id)
  35. document = DocumentService.get_document(dataset.id, document_id)
  36. if not document:
  37. raise NotFound('Document not found.')
  38. # check embedding model setting
  39. if dataset.indexing_technique == 'high_quality':
  40. try:
  41. model_manager = ModelManager()
  42. model_manager.get_model_instance(
  43. tenant_id=current_user.current_tenant_id,
  44. provider=dataset.embedding_model_provider,
  45. model_type=ModelType.TEXT_EMBEDDING,
  46. model=dataset.embedding_model
  47. )
  48. except LLMBadRequestError:
  49. raise ProviderNotInitializeError(
  50. "No Embedding Model available. Please configure a valid provider "
  51. "in the Settings -> Model Provider.")
  52. except ProviderTokenNotInitError as ex:
  53. raise ProviderNotInitializeError(ex.description)
  54. # validate args
  55. parser = reqparse.RequestParser()
  56. parser.add_argument('segments', type=list, required=False, nullable=True, location='json')
  57. args = parser.parse_args()
  58. for args_item in args['segments']:
  59. SegmentService.segment_create_args_validate(args_item, document)
  60. segments = SegmentService.multi_create_segment(args['segments'], document, dataset)
  61. return {
  62. 'data': marshal(segments, segment_fields),
  63. 'doc_form': document.doc_form
  64. }, 200
  65. def get(self, tenant_id, dataset_id, document_id):
  66. """Create single segment."""
  67. # check dataset
  68. dataset_id = str(dataset_id)
  69. tenant_id = str(tenant_id)
  70. dataset = db.session.query(Dataset).filter(
  71. Dataset.tenant_id == tenant_id,
  72. Dataset.id == dataset_id
  73. ).first()
  74. if not dataset:
  75. raise NotFound('Dataset not found.')
  76. # check document
  77. document_id = str(document_id)
  78. document = DocumentService.get_document(dataset.id, document_id)
  79. if not document:
  80. raise NotFound('Document not found.')
  81. # check embedding model setting
  82. if dataset.indexing_technique == 'high_quality':
  83. try:
  84. model_manager = ModelManager()
  85. model_manager.get_model_instance(
  86. tenant_id=current_user.current_tenant_id,
  87. provider=dataset.embedding_model_provider,
  88. model_type=ModelType.TEXT_EMBEDDING,
  89. model=dataset.embedding_model
  90. )
  91. except LLMBadRequestError:
  92. raise ProviderNotInitializeError(
  93. "No Embedding Model available. Please configure a valid provider "
  94. "in the Settings -> Model Provider.")
  95. except ProviderTokenNotInitError as ex:
  96. raise ProviderNotInitializeError(ex.description)
  97. parser = reqparse.RequestParser()
  98. parser.add_argument('status', type=str,
  99. action='append', default=[], location='args')
  100. parser.add_argument('keyword', type=str, default=None, location='args')
  101. args = parser.parse_args()
  102. status_list = args['status']
  103. keyword = args['keyword']
  104. query = DocumentSegment.query.filter(
  105. DocumentSegment.document_id == str(document_id),
  106. DocumentSegment.tenant_id == current_user.current_tenant_id
  107. )
  108. if status_list:
  109. query = query.filter(DocumentSegment.status.in_(status_list))
  110. if keyword:
  111. query = query.where(DocumentSegment.content.ilike(f'%{keyword}%'))
  112. total = query.count()
  113. segments = query.order_by(DocumentSegment.position).all()
  114. return {
  115. 'data': marshal(segments, segment_fields),
  116. 'doc_form': document.doc_form,
  117. 'total': total
  118. }, 200
  119. class DatasetSegmentApi(DatasetApiResource):
  120. def delete(self, tenant_id, dataset_id, document_id, segment_id):
  121. # check dataset
  122. dataset_id = str(dataset_id)
  123. tenant_id = str(tenant_id)
  124. dataset = db.session.query(Dataset).filter(
  125. Dataset.tenant_id == tenant_id,
  126. Dataset.id == dataset_id
  127. ).first()
  128. if not dataset:
  129. raise NotFound('Dataset not found.')
  130. # check user's model setting
  131. DatasetService.check_dataset_model_setting(dataset)
  132. # check document
  133. document_id = str(document_id)
  134. document = DocumentService.get_document(dataset_id, document_id)
  135. if not document:
  136. raise NotFound('Document not found.')
  137. # check segment
  138. segment = DocumentSegment.query.filter(
  139. DocumentSegment.id == str(segment_id),
  140. DocumentSegment.tenant_id == current_user.current_tenant_id
  141. ).first()
  142. if not segment:
  143. raise NotFound('Segment not found.')
  144. SegmentService.delete_segment(segment, document, dataset)
  145. return {'result': 'success'}, 200
  146. @cloud_edition_billing_resource_check('vector_space', 'dataset')
  147. def post(self, tenant_id, dataset_id, document_id, segment_id):
  148. # check dataset
  149. dataset_id = str(dataset_id)
  150. tenant_id = str(tenant_id)
  151. dataset = db.session.query(Dataset).filter(
  152. Dataset.tenant_id == tenant_id,
  153. Dataset.id == dataset_id
  154. ).first()
  155. if not dataset:
  156. raise NotFound('Dataset not found.')
  157. # check user's model setting
  158. DatasetService.check_dataset_model_setting(dataset)
  159. # check document
  160. document_id = str(document_id)
  161. document = DocumentService.get_document(dataset_id, document_id)
  162. if not document:
  163. raise NotFound('Document not found.')
  164. if dataset.indexing_technique == 'high_quality':
  165. # check embedding model setting
  166. try:
  167. model_manager = ModelManager()
  168. model_manager.get_model_instance(
  169. tenant_id=current_user.current_tenant_id,
  170. provider=dataset.embedding_model_provider,
  171. model_type=ModelType.TEXT_EMBEDDING,
  172. model=dataset.embedding_model
  173. )
  174. except LLMBadRequestError:
  175. raise ProviderNotInitializeError(
  176. "No Embedding Model available. Please configure a valid provider "
  177. "in the Settings -> Model Provider.")
  178. except ProviderTokenNotInitError as ex:
  179. raise ProviderNotInitializeError(ex.description)
  180. # check segment
  181. segment_id = str(segment_id)
  182. segment = DocumentSegment.query.filter(
  183. DocumentSegment.id == str(segment_id),
  184. DocumentSegment.tenant_id == current_user.current_tenant_id
  185. ).first()
  186. if not segment:
  187. raise NotFound('Segment not found.')
  188. # validate args
  189. parser = reqparse.RequestParser()
  190. parser.add_argument('segment', type=dict, required=False, nullable=True, location='json')
  191. args = parser.parse_args()
  192. SegmentService.segment_create_args_validate(args['segment'], document)
  193. segment = SegmentService.update_segment(args['segment'], segment, document, dataset)
  194. return {
  195. 'data': marshal(segment, segment_fields),
  196. 'doc_form': document.doc_form
  197. }, 200
  198. api.add_resource(SegmentApi, '/datasets/<uuid:dataset_id>/documents/<uuid:document_id>/segments')
  199. api.add_resource(DatasetSegmentApi, '/datasets/<uuid:dataset_id>/documents/<uuid:document_id>/segments/<uuid:segment_id>')