您最多选择25个主题 主题必须以字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符

datasource.py 9.6KB

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