difyService.py 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196
  1. import json
  2. from datetime import datetime
  3. import httpx
  4. from typing import Union, Dict, List
  5. from fastapi import HTTPException
  6. from starlette import status
  7. from app.config.config import settings
  8. from app.utils.rsa_crypto import RagflowCrypto
  9. class DifyService:
  10. def __init__(self, base_url: str):
  11. self.base_url = base_url
  12. def _handle_response(self, response: httpx.Response) -> Union[Dict, List]:
  13. if response.status_code != 200:
  14. if response.status_code == 201:
  15. return response.json()
  16. return {}
  17. data = response.json()
  18. ret_code = data.get("retcode")
  19. if ret_code == 401:
  20. raise HTTPException(
  21. status_code=status.HTTP_401_UNAUTHORIZED,
  22. detail="登录过期",
  23. )
  24. # if ret_code != 0:
  25. # return {}
  26. # 检查返回的数据类型
  27. if isinstance(data.get("data"), dict):
  28. return data.get("data", {})
  29. elif isinstance(data.get("data"), list):
  30. return data.get("data", [])
  31. else:
  32. return data
  33. async def register(self, username: str, password: str):
  34. password = RagflowCrypto(settings.PUBLIC_KEY, settings.PRIVATE_KEY).encrypt(password)
  35. async with httpx.AsyncClient() as client:
  36. response = await client.post(
  37. f"{self.base_url}/v1/user/register",
  38. headers={'Content-Type': 'application/json'},
  39. json={"nickname": username, "email": f"{username}@example.com", "password": password}
  40. )
  41. if response.status_code != 200:
  42. raise Exception(f"Ragflow registration failed: {response.text}")
  43. return self._handle_response(response)
  44. async def login(self, username: str, password: str) -> str:
  45. password = RagflowCrypto(settings.PUBLIC_KEY, settings.PRIVATE_KEY).encrypt(password)
  46. async with httpx.AsyncClient() as client:
  47. response = await client.post(
  48. f"{self.base_url}/v1/user/login",
  49. headers={'Content-Type': 'application/json'},
  50. json={"email": f"{username}@example.com", "password": password}
  51. )
  52. if response.status_code != 200:
  53. raise Exception(f"Ragflow login failed: {response.text}")
  54. authorization = response.headers.get('Authorization')
  55. if not authorization:
  56. raise Exception("Authorization header not found in response")
  57. return authorization
  58. async def chat(self, token: str, user_id: int, message: str, upload_file_id: str, conversation_id: str):
  59. target_url = f"{self.base_url}/v1/chat-messages"
  60. files = []
  61. if upload_file_id:
  62. files = [
  63. {
  64. "type": "image",
  65. "transfer_method": "local_file",
  66. "url": "",
  67. "upload_file_id": upload_file_id
  68. }
  69. ]
  70. data = {
  71. "inputs": {},
  72. "query": message,
  73. "response_mode": "streaming",
  74. "conversation_id": conversation_id,
  75. "user": str(user_id),
  76. "files": files
  77. }
  78. async with httpx.AsyncClient(timeout=300.0) as client:
  79. headers = {
  80. 'Content-Type': 'application/json',
  81. 'Authorization': f'Bearer {token}'
  82. }
  83. async with client.stream("POST", target_url, data=json.dumps(data), headers=headers) as response:
  84. if response.status_code == 200:
  85. try:
  86. async for answer in response.aiter_text():
  87. # print(f"response of ragflow chat: {answer}")
  88. yield answer
  89. except GeneratorExit as e:
  90. print(e)
  91. return
  92. else:
  93. yield f"Error: {response.status_code}"
  94. async def get_session_history(self, token: str, conversation_id: str, user: str):
  95. url = f"{self.base_url}/v1/messages"
  96. params = {
  97. 'user': user,
  98. 'conversation_id': conversation_id
  99. }
  100. headers = {"Authorization": f'Bearer {token}'}
  101. async with httpx.AsyncClient() as client:
  102. response = await client.get(url, params=params, headers=headers)
  103. # print(response.text)
  104. # print(response.status_code)
  105. # print(response.res)
  106. data = self._handle_response(response)
  107. # print("----------------data----------------------:", data)
  108. return data
  109. async def upload(self, token: str, filename: str, file: bytes, user_id) -> dict:
  110. url = f"{self.base_url}/v1/files/upload"
  111. headers = {
  112. # 'Content-Type': 'application/json',
  113. 'Authorization': f'Bearer {token}'
  114. }
  115. data = {
  116. 'user': str(user_id)
  117. }
  118. # 创建表单数据,包含文件
  119. files = {"file": (filename, file)}
  120. async with httpx.AsyncClient() as client:
  121. response = await client.post(url, headers=headers, files=files, data=data)
  122. data = self._handle_response(response)
  123. return data
  124. async def save_images(self, url: str, filename: str):
  125. url = f"{self.base_url}{url}"
  126. async with httpx.AsyncClient() as client:
  127. response = await client.get(url)
  128. response.raise_for_status()
  129. # 打开一个文件用于写入
  130. with open(f"app/images/{filename}", 'wb') as f:
  131. # 写入请求的内容
  132. f.write(response.content)
  133. async def workflow(self, token: str, user_id: int, inputs: dict):
  134. target_url = f"{self.base_url}/v1/workflows/run"
  135. data = {
  136. "inputs": inputs,
  137. "response_mode": "streaming",
  138. "user": str(user_id),
  139. "files":[]
  140. }
  141. async with httpx.AsyncClient(timeout=1800) as client:
  142. headers = {
  143. 'Content-Type': 'application/json',
  144. 'Authorization': f'Bearer {token}'
  145. }
  146. async with client.stream("POST", target_url, data=json.dumps(data), headers=headers) as response:
  147. if response.status_code == 200:
  148. try:
  149. async for answer in response.aiter_text():
  150. # print(f"response of ragflow chat: {answer}")
  151. yield answer
  152. except GeneratorExit as e:
  153. print(e)
  154. return
  155. else:
  156. yield f"Error: {response.status_code}"
  157. if __name__ == "__main__":
  158. async def a():
  159. a = DifyService("http://192.168.20.116")
  160. b = await a.get_session_history("app-YmOAMDsPpDDlqryMHnc9TzTO", "f94c6328-8ff0-4713-af3f-e823d547682d",
  161. "63")
  162. print(b)
  163. import asyncio
  164. asyncio.run(a())