Вы не можете выбрать более 25 тем Темы должны начинаться с буквы или цифры, могут содержать дефисы(-) и должны содержать не более 35 символов.

datasource.py 9.5KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253
  1. from typing import Any, Mapping
  2. from core.datasource.entities.api_entities import DatasourceProviderApiEntity
  3. from core.datasource.entities.datasource_entities import (
  4. GetOnlineDocumentPageContentRequest,
  5. GetOnlineDocumentPageContentResponse,
  6. GetOnlineDocumentPagesResponse,
  7. GetWebsiteCrawlResponse,
  8. )
  9. from core.plugin.entities.plugin import GenericProviderID, ToolProviderID
  10. from core.plugin.entities.plugin_daemon import (
  11. PluginBasicBooleanResponse,
  12. PluginDatasourceProviderEntity,
  13. )
  14. from core.plugin.impl.base import BasePluginClient
  15. class PluginDatasourceManager(BasePluginClient):
  16. def fetch_datasource_providers(self, tenant_id: str) -> list[DatasourceProviderApiEntity]:
  17. """
  18. Fetch datasource providers for the given tenant.
  19. """
  20. def transformer(json_response: dict[str, Any]) -> dict:
  21. for provider in json_response.get("data", []):
  22. declaration = provider.get("declaration", {}) or {}
  23. provider_name = declaration.get("identity", {}).get("name")
  24. for datasource in declaration.get("datasources", []):
  25. datasource["identity"]["provider"] = provider_name
  26. return json_response
  27. # response = self._request_with_plugin_daemon_response(
  28. # "GET",
  29. # f"plugin/{tenant_id}/management/datasources",
  30. # list[PluginDatasourceProviderEntity],
  31. # params={"page": 1, "page_size": 256},
  32. # transformer=transformer,
  33. # )
  34. # for provider in response:
  35. # provider.declaration.identity.name = f"{provider.plugin_id}/{provider.declaration.identity.name}"
  36. # # override the provider name for each tool to plugin_id/provider_name
  37. # for datasource in provider.declaration.datasources:
  38. # datasource.identity.provider = provider.declaration.identity.name
  39. return [DatasourceProviderApiEntity(**self._get_local_file_datasource_provider())]
  40. def fetch_datasource_provider(self, tenant_id: str, provider: str) -> PluginDatasourceProviderEntity:
  41. """
  42. Fetch datasource provider for the given tenant and plugin.
  43. """
  44. tool_provider_id = ToolProviderID(provider)
  45. def transformer(json_response: dict[str, Any]) -> dict:
  46. data = json_response.get("data")
  47. if data:
  48. for datasource in data.get("declaration", {}).get("datasources", []):
  49. datasource["identity"]["provider"] = tool_provider_id.provider_name
  50. return json_response
  51. response = self._request_with_plugin_daemon_response(
  52. "GET",
  53. f"plugin/{tenant_id}/management/datasources",
  54. PluginDatasourceProviderEntity,
  55. params={"provider": tool_provider_id.provider_name, "plugin_id": tool_provider_id.plugin_id},
  56. transformer=transformer,
  57. )
  58. response.declaration.identity.name = f"{response.plugin_id}/{response.declaration.identity.name}"
  59. # override the provider name for each tool to plugin_id/provider_name
  60. for datasource in response.declaration.datasources:
  61. datasource.identity.provider = response.declaration.identity.name
  62. return response
  63. def get_website_crawl(
  64. self,
  65. tenant_id: str,
  66. user_id: str,
  67. datasource_provider: str,
  68. datasource_name: str,
  69. credentials: dict[str, Any],
  70. datasource_parameters: Mapping[str, Any],
  71. provider_type: str,
  72. ) -> GetWebsiteCrawlResponse:
  73. """
  74. Invoke the datasource with the given tenant, user, plugin, provider, name, credentials and parameters.
  75. """
  76. datasource_provider_id = GenericProviderID(datasource_provider)
  77. response = self._request_with_plugin_daemon_response_stream(
  78. "POST",
  79. f"plugin/{tenant_id}/dispatch/datasource/get_website_crawl",
  80. GetWebsiteCrawlResponse,
  81. data={
  82. "user_id": user_id,
  83. "data": {
  84. "provider": datasource_provider_id.provider_name,
  85. "datasource": datasource_name,
  86. "credentials": credentials,
  87. "datasource_parameters": datasource_parameters,
  88. },
  89. },
  90. headers={
  91. "X-Plugin-ID": datasource_provider_id.plugin_id,
  92. "Content-Type": "application/json",
  93. },
  94. )
  95. for resp in response:
  96. return resp
  97. raise Exception("No response from plugin daemon")
  98. def get_online_document_pages(
  99. self,
  100. tenant_id: str,
  101. user_id: str,
  102. datasource_provider: str,
  103. datasource_name: str,
  104. credentials: dict[str, Any],
  105. datasource_parameters: Mapping[str, Any],
  106. provider_type: str,
  107. ) -> GetOnlineDocumentPagesResponse:
  108. """
  109. Invoke the datasource with the given tenant, user, plugin, provider, name, credentials and parameters.
  110. """
  111. datasource_provider_id = GenericProviderID(datasource_provider)
  112. response = self._request_with_plugin_daemon_response_stream(
  113. "POST",
  114. f"plugin/{tenant_id}/dispatch/datasource/get_online_document_pages",
  115. GetOnlineDocumentPagesResponse,
  116. data={
  117. "user_id": user_id,
  118. "data": {
  119. "provider": datasource_provider_id.provider_name,
  120. "datasource": datasource_name,
  121. "credentials": credentials,
  122. "datasource_parameters": datasource_parameters,
  123. },
  124. },
  125. headers={
  126. "X-Plugin-ID": datasource_provider_id.plugin_id,
  127. "Content-Type": "application/json",
  128. },
  129. )
  130. for resp in response:
  131. return resp
  132. raise Exception("No response from plugin daemon")
  133. def get_online_document_page_content(
  134. self,
  135. tenant_id: str,
  136. user_id: str,
  137. datasource_provider: str,
  138. datasource_name: str,
  139. credentials: dict[str, Any],
  140. datasource_parameters: GetOnlineDocumentPageContentRequest,
  141. provider_type: str,
  142. ) -> GetOnlineDocumentPageContentResponse:
  143. """
  144. Invoke the datasource with the given tenant, user, plugin, provider, name, credentials and parameters.
  145. """
  146. datasource_provider_id = GenericProviderID(datasource_provider)
  147. response = self._request_with_plugin_daemon_response_stream(
  148. "POST",
  149. f"plugin/{tenant_id}/dispatch/datasource/get_online_document_page_content",
  150. GetOnlineDocumentPageContentResponse,
  151. data={
  152. "user_id": user_id,
  153. "data": {
  154. "provider": datasource_provider_id.provider_name,
  155. "datasource": datasource_name,
  156. "credentials": credentials,
  157. "datasource_parameters": datasource_parameters,
  158. },
  159. },
  160. headers={
  161. "X-Plugin-ID": datasource_provider_id.plugin_id,
  162. "Content-Type": "application/json",
  163. },
  164. )
  165. for resp in response:
  166. return resp
  167. raise Exception("No response from plugin daemon")
  168. def validate_provider_credentials(
  169. self, tenant_id: str, user_id: str, provider: str, credentials: dict[str, Any]
  170. ) -> bool:
  171. """
  172. validate the credentials of the provider
  173. """
  174. tool_provider_id = GenericProviderID(provider)
  175. response = self._request_with_plugin_daemon_response_stream(
  176. "POST",
  177. f"plugin/{tenant_id}/dispatch/datasource/validate_credentials",
  178. PluginBasicBooleanResponse,
  179. data={
  180. "user_id": user_id,
  181. "data": {
  182. "provider": tool_provider_id.provider_name,
  183. "credentials": credentials,
  184. },
  185. },
  186. headers={
  187. "X-Plugin-ID": tool_provider_id.plugin_id,
  188. "Content-Type": "application/json",
  189. },
  190. )
  191. for resp in response:
  192. return resp.result
  193. return False
  194. def _get_local_file_datasource_provider(self) -> dict[str, Any]:
  195. return {
  196. "id": "langgenius/file/file",
  197. "author": "langgenius",
  198. "name": "langgenius/file/file",
  199. "plugin_id": "langgenius/file",
  200. "plugin_unique_identifier": "langgenius/file:0.0.1@dify",
  201. "description": {"zh_Hans": "File", "en_US": "File", "pt_BR": "File", "ja_JP": "File"},
  202. "icon": "https://cloud.dify.ai/console/api/workspaces/current/plugin/icon?tenant_id=945b4365-9d99-48c1-8c47-90593fe8b9c9&filename=13d9312f6b1352d3939b90a5257de58ff3cd619d5be4f5b266ff0298935ac328.svg",
  203. "label": {"zh_Hans": "File", "en_US": "File", "pt_BR": "File", "ja_JP": "File"},
  204. "type": "datasource",
  205. "team_credentials": {},
  206. "is_team_authorization": False,
  207. "allow_delete": True,
  208. "datasources": [
  209. {
  210. "author": "langgenius",
  211. "name": "upload_file",
  212. "label": {"en_US": "File", "zh_Hans": "File", "pt_BR": "File", "ja_JP": "File"},
  213. "description": {"en_US": "File", "zh_Hans": "File", "pt_BR": "File", "ja_JP": "File."},
  214. "parameters": [],
  215. "labels": ["search"],
  216. "output_schema": None,
  217. }
  218. ],
  219. "labels": ["search"],
  220. }