ragflow.py 8.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215
  1. import httpx
  2. from typing import Union, Dict, List
  3. from fastapi import HTTPException
  4. from starlette import status
  5. from Log import logger
  6. from app.config.config import settings
  7. from app.utils.rsa_crypto import RagflowCrypto
  8. class RagflowService:
  9. def __init__(self, base_url: str):
  10. self.base_url = base_url
  11. def _handle_response(self, response: httpx.Response) -> Union[Dict, List]:
  12. if response.status_code != 200:
  13. return {}
  14. data = response.json()
  15. ret_code = data.get("retcode")
  16. if ret_code == 401:
  17. raise HTTPException(
  18. status_code=status.HTTP_401_UNAUTHORIZED,
  19. detail="登录过期",
  20. )
  21. if ret_code != 0:
  22. return {}
  23. # 检查返回的数据类型
  24. if isinstance(data.get("data"), dict):
  25. return data.get("data", {})
  26. elif isinstance(data.get("data"), list):
  27. return data.get("data", [])
  28. else:
  29. return {}
  30. async def register(self, username: str, password: str):
  31. password = RagflowCrypto(settings.PUBLIC_KEY, settings.PRIVATE_KEY).encrypt(password)
  32. async with httpx.AsyncClient() as client:
  33. response = await client.post(
  34. f"{self.base_url}/v1/user/register",
  35. headers={'Content-Type': 'application/json'},
  36. json={"nickname": username, "email": f"{username}@example.com", "password": password}
  37. )
  38. if response.status_code != 200:
  39. raise Exception(f"Ragflow registration failed: {response.text}")
  40. return self._handle_response(response)
  41. async def login(self, username: str, password: str) -> str:
  42. password = RagflowCrypto(settings.PUBLIC_KEY, settings.PRIVATE_KEY).encrypt(password)
  43. async with httpx.AsyncClient() as client:
  44. response = await client.post(
  45. f"{self.base_url}/v1/user/login",
  46. headers={'Content-Type': 'application/json'},
  47. json={"email": f"{username}@example.com", "password": password}
  48. )
  49. if response.status_code != 200:
  50. raise Exception(f"Ragflow login failed: {response.text}")
  51. authorization = response.headers.get('Authorization')
  52. if not authorization:
  53. raise Exception("Authorization header not found in response")
  54. return authorization
  55. async def chat(self, token: str, chat_id: str, chat_history: list):
  56. data = {
  57. "conversation_id": chat_id,
  58. "messages": chat_history
  59. }
  60. print(f"send to ragflow chat: {data}")
  61. target_url = f"{self.base_url}/v1/conversation/completion"
  62. async with httpx.AsyncClient(timeout=300.0) as client:
  63. headers = {
  64. 'Content-Type': 'application/json',
  65. 'Authorization': token
  66. }
  67. async with client.stream("POST", target_url, json=data, headers=headers) as response:
  68. if response.status_code == 200:
  69. try:
  70. async for answer in response.aiter_text():
  71. print(f"response of ragflow chat: {answer}")
  72. yield answer
  73. except GeneratorExit as e:
  74. print(e)
  75. return
  76. else:
  77. yield f"Error: {response.status_code}"
  78. async def get_chat_sessions(self, token: str, dialog_id: str) -> list:
  79. url = f"{self.base_url}/v1/conversation/list?dialog_id={dialog_id}"
  80. headers = {"Authorization": token}
  81. async with httpx.AsyncClient() as client:
  82. response = await client.get(url, headers=headers)
  83. data = self._handle_response(response)
  84. result = [
  85. {
  86. "id": item["id"],
  87. "name": item["name"],
  88. "updated_time": item["update_time"]
  89. }
  90. for item in data
  91. if "id" in item and "name" in item and item["name"]
  92. ]
  93. return result
  94. async def get_session_log(self, token: str, conversation_id: str) -> dict:
  95. url = f"{self.base_url}/v1/conversation/get?conversation_id={conversation_id}"
  96. headers = {"Authorization": token}
  97. async with httpx.AsyncClient() as client:
  98. response = await client.get(url, headers=headers)
  99. data = self._handle_response(response)
  100. session_log = {
  101. "session_log": [
  102. {
  103. "message": message.get("content"),
  104. "role": message.get("role"),
  105. }
  106. for message in data.get("message", [])
  107. ],
  108. "reference": data.get("reference"),
  109. }
  110. return session_log
  111. async def set_session(self, token: str, dialog_id: str, message: dict, chat_id: str, is_new: bool) -> list:
  112. url = f"{self.base_url}/v1/conversation/set?dialog_id={dialog_id}"
  113. headers = {"Authorization": token}
  114. data = {
  115. "dialog_id": dialog_id,
  116. "name": message["message"],
  117. "is_new": is_new,
  118. "conversation_id": chat_id,
  119. }
  120. async with httpx.AsyncClient() as client:
  121. response = await client.post(url, headers=headers, json=data)
  122. data = self._handle_response(response)
  123. return [
  124. {
  125. "content": "你好! 我是你的助理,有什么可以帮到你的吗?",
  126. "role": "assistant"
  127. },
  128. {
  129. "content": message["message"],
  130. "doc_ids":message.get("doc_ids", []),
  131. "role": "user"
  132. }
  133. ] if data else []
  134. async def get_session_history(self, token: str, chat_id: str) -> list:
  135. url = f"{self.base_url}/v1/conversation/get?conversation_id={chat_id}"
  136. headers = {"Authorization": token}
  137. async with httpx.AsyncClient() as client:
  138. response = await client.get(url, headers=headers)
  139. data = self._handle_response(response)
  140. return data.get("message", [])
  141. async def upload_and_parse(self, token: str, chat_id: str, filename: str, file: bytes) -> str:
  142. url = f"{self.base_url}/v1/document/upload_and_parse"
  143. headers = {"Authorization": token}
  144. data = {"conversation_id": chat_id}
  145. # 创建表单数据,包含文件
  146. files = {"file": (filename, file)}
  147. async with httpx.AsyncClient(timeout=60) as client:
  148. response = await client.post(url, headers=headers, files=files, data=data)
  149. data = self._handle_response(response)
  150. return data
  151. async def add_user_tenant(self, token: str, tenant_id: str, email: str, user_id: str) -> str:
  152. url = f"{self.base_url}/v1/tenant/{tenant_id}/user"
  153. headers = {"Authorization": token}
  154. data = {"email": email, "user_id": user_id}
  155. async with httpx.AsyncClient(timeout=60) as client:
  156. response = await client.post(url, headers=headers, json=data)
  157. if response.status_code != 200:
  158. raise Exception(f"Ragflow add user to tenant failed: {response.text}")
  159. async def get_knowledge_list(self, token: str, page_index: int, page_size: int) -> str:
  160. url = f"{self.base_url}/v1/kb/list"
  161. headers = {"Authorization": token}
  162. params = {"page": page_index, "page_size": page_size}
  163. async with httpx.AsyncClient(timeout=60) as client:
  164. response = await client.get(url, headers=headers, params=params)
  165. res = self._handle_response(response)
  166. print(res)
  167. return res
  168. async def set_user_password(self, token: str, password: str, new_password: str) -> str:
  169. # print("password:", password)
  170. # print("new_password:", new_password)
  171. password = RagflowCrypto(settings.PUBLIC_KEY, settings.PRIVATE_KEY).encrypt(password)
  172. new_password = RagflowCrypto(settings.PUBLIC_KEY, settings.PRIVATE_KEY).encrypt(new_password)
  173. url = f"{self.base_url}/v1/user/setting"
  174. headers = {"Authorization": token}
  175. data = {"password": password, "new_password":new_password}
  176. async with httpx.AsyncClient(timeout=60) as client:
  177. response = await client.post(url, headers=headers, data=data)
  178. data = self._handle_response(response)
  179. logger.info("set_user_password:{}".format(data))
  180. return data
  181. if __name__ == "__main__":
  182. async def a():
  183. a = RagflowService("http://192.168.20.119:11080")
  184. b = await a.get_knowledge_list("625e1f24a26811ef8f940242ac130006", 1,
  185. 10)
  186. print(b)
  187. import asyncio
  188. # 在同步代码中启动异步主函数
  189. asyncio.run(a())