plugin.py 8.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243
  1. from collections.abc import Sequence
  2. from core.plugin.entities.bundle import PluginBundleDependency
  3. from core.plugin.entities.plugin import (
  4. GenericProviderID,
  5. PluginDeclaration,
  6. PluginEntity,
  7. PluginInstallation,
  8. PluginInstallationSource,
  9. )
  10. from core.plugin.entities.plugin_daemon import PluginInstallTask, PluginInstallTaskStartResponse, PluginUploadResponse
  11. from core.plugin.manager.base import BasePluginManager
  12. class PluginInstallationManager(BasePluginManager):
  13. def fetch_plugin_by_identifier(
  14. self,
  15. tenant_id: str,
  16. identifier: str,
  17. ) -> bool:
  18. return self._request_with_plugin_daemon_response(
  19. "GET",
  20. f"plugin/{tenant_id}/management/fetch/identifier",
  21. bool,
  22. params={"plugin_unique_identifier": identifier},
  23. )
  24. def list_plugins(self, tenant_id: str) -> list[PluginEntity]:
  25. return self._request_with_plugin_daemon_response(
  26. "GET",
  27. f"plugin/{tenant_id}/management/list",
  28. list[PluginEntity],
  29. params={"page": 1, "page_size": 256},
  30. )
  31. def upload_pkg(
  32. self,
  33. tenant_id: str,
  34. pkg: bytes,
  35. verify_signature: bool = False,
  36. ) -> PluginUploadResponse:
  37. """
  38. Upload a plugin package and return the plugin unique identifier.
  39. """
  40. body = {
  41. "dify_pkg": ("dify_pkg", pkg, "application/octet-stream"),
  42. }
  43. data = {
  44. "verify_signature": "true" if verify_signature else "false",
  45. }
  46. return self._request_with_plugin_daemon_response(
  47. "POST",
  48. f"plugin/{tenant_id}/management/install/upload/package",
  49. PluginUploadResponse,
  50. files=body,
  51. data=data,
  52. )
  53. def upload_bundle(
  54. self,
  55. tenant_id: str,
  56. bundle: bytes,
  57. verify_signature: bool = False,
  58. ) -> Sequence[PluginBundleDependency]:
  59. """
  60. Upload a plugin bundle and return the dependencies.
  61. """
  62. return self._request_with_plugin_daemon_response(
  63. "POST",
  64. f"plugin/{tenant_id}/management/install/upload/bundle",
  65. list[PluginBundleDependency],
  66. files={"dify_bundle": ("dify_bundle", bundle, "application/octet-stream")},
  67. data={"verify_signature": "true" if verify_signature else "false"},
  68. )
  69. def install_from_identifiers(
  70. self, tenant_id: str, identifiers: Sequence[str], source: PluginInstallationSource, meta: dict
  71. ) -> PluginInstallTaskStartResponse:
  72. """
  73. Install a plugin from an identifier.
  74. """
  75. # exception will be raised if the request failed
  76. return self._request_with_plugin_daemon_response(
  77. "POST",
  78. f"plugin/{tenant_id}/management/install/identifiers",
  79. PluginInstallTaskStartResponse,
  80. data={
  81. "plugin_unique_identifiers": identifiers,
  82. "source": source,
  83. "meta": meta,
  84. },
  85. headers={"Content-Type": "application/json"},
  86. )
  87. def fetch_plugin_installation_tasks(self, tenant_id: str, page: int, page_size: int) -> Sequence[PluginInstallTask]:
  88. """
  89. Fetch plugin installation tasks.
  90. """
  91. return self._request_with_plugin_daemon_response(
  92. "GET",
  93. f"plugin/{tenant_id}/management/install/tasks",
  94. list[PluginInstallTask],
  95. params={"page": page, "page_size": page_size},
  96. )
  97. def fetch_plugin_installation_task(self, tenant_id: str, task_id: str) -> PluginInstallTask:
  98. """
  99. Fetch a plugin installation task.
  100. """
  101. return self._request_with_plugin_daemon_response(
  102. "GET",
  103. f"plugin/{tenant_id}/management/install/tasks/{task_id}",
  104. PluginInstallTask,
  105. )
  106. def delete_plugin_installation_task(self, tenant_id: str, task_id: str) -> bool:
  107. """
  108. Delete a plugin installation task.
  109. """
  110. return self._request_with_plugin_daemon_response(
  111. "POST",
  112. f"plugin/{tenant_id}/management/install/tasks/{task_id}/delete",
  113. bool,
  114. )
  115. def delete_all_plugin_installation_task_items(self, tenant_id: str) -> bool:
  116. """
  117. Delete all plugin installation task items.
  118. """
  119. return self._request_with_plugin_daemon_response(
  120. "POST",
  121. f"plugin/{tenant_id}/management/install/tasks/delete_all",
  122. bool,
  123. )
  124. def delete_plugin_installation_task_item(self, tenant_id: str, task_id: str, identifier: str) -> bool:
  125. """
  126. Delete a plugin installation task item.
  127. """
  128. return self._request_with_plugin_daemon_response(
  129. "POST",
  130. f"plugin/{tenant_id}/management/install/tasks/{task_id}/delete/{identifier}",
  131. bool,
  132. )
  133. def fetch_plugin_manifest(self, tenant_id: str, plugin_unique_identifier: str) -> PluginDeclaration:
  134. """
  135. Fetch a plugin manifest.
  136. """
  137. return self._request_with_plugin_daemon_response(
  138. "GET",
  139. f"plugin/{tenant_id}/management/fetch/manifest",
  140. PluginDeclaration,
  141. params={"plugin_unique_identifier": plugin_unique_identifier},
  142. )
  143. def fetch_plugin_installation_by_ids(
  144. self, tenant_id: str, plugin_ids: Sequence[str]
  145. ) -> Sequence[PluginInstallation]:
  146. """
  147. Fetch plugin installations by ids.
  148. """
  149. return self._request_with_plugin_daemon_response(
  150. "POST",
  151. f"plugin/{tenant_id}/management/installation/fetch/batch",
  152. list[PluginInstallation],
  153. data={"plugin_ids": plugin_ids},
  154. headers={"Content-Type": "application/json"},
  155. )
  156. def fetch_missing_dependencies(self, tenant_id: str, plugin_unique_identifiers: list[str]) -> list[str]:
  157. """
  158. Fetch missing dependencies
  159. """
  160. return self._request_with_plugin_daemon_response(
  161. "POST",
  162. f"plugin/{tenant_id}/management/installation/missing",
  163. list[str],
  164. data={"plugin_unique_identifiers": plugin_unique_identifiers},
  165. headers={"Content-Type": "application/json"},
  166. )
  167. def uninstall(self, tenant_id: str, plugin_installation_id: str) -> bool:
  168. """
  169. Uninstall a plugin.
  170. """
  171. return self._request_with_plugin_daemon_response(
  172. "POST",
  173. f"plugin/{tenant_id}/management/uninstall",
  174. bool,
  175. data={
  176. "plugin_installation_id": plugin_installation_id,
  177. },
  178. headers={"Content-Type": "application/json"},
  179. )
  180. def upgrade_plugin(
  181. self,
  182. tenant_id: str,
  183. original_plugin_unique_identifier: str,
  184. new_plugin_unique_identifier: str,
  185. source: PluginInstallationSource,
  186. meta: dict,
  187. ) -> PluginInstallTaskStartResponse:
  188. """
  189. Upgrade a plugin.
  190. """
  191. return self._request_with_plugin_daemon_response(
  192. "POST",
  193. f"plugin/{tenant_id}/management/install/upgrade",
  194. PluginInstallTaskStartResponse,
  195. data={
  196. "original_plugin_unique_identifier": original_plugin_unique_identifier,
  197. "new_plugin_unique_identifier": new_plugin_unique_identifier,
  198. "source": source,
  199. "meta": meta,
  200. },
  201. headers={"Content-Type": "application/json"},
  202. )
  203. def check_tools_existence(self, tenant_id: str, provider_ids: Sequence[GenericProviderID]) -> Sequence[bool]:
  204. """
  205. Check if the tools exist
  206. """
  207. return self._request_with_plugin_daemon_response(
  208. "POST",
  209. f"plugin/{tenant_id}/management/tools/check_existence",
  210. list[bool],
  211. data={
  212. "provider_ids": [
  213. {
  214. "plugin_id": provider_id.plugin_id,
  215. "provider_name": provider_id.provider_name,
  216. }
  217. for provider_id in provider_ids
  218. ]
  219. },
  220. headers={"Content-Type": "application/json"},
  221. )