plugin.py 8.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264
  1. import io
  2. from flask import request, send_file
  3. from flask_login import current_user
  4. from flask_restful import Resource, reqparse
  5. from werkzeug.exceptions import Forbidden
  6. from configs import dify_config
  7. from controllers.console import api
  8. from controllers.console.setup import setup_required
  9. from controllers.console.wraps import account_initialization_required
  10. from core.model_runtime.utils.encoders import jsonable_encoder
  11. from libs.login import login_required
  12. from services.plugin.plugin_service import PluginService
  13. class PluginDebuggingKeyApi(Resource):
  14. @setup_required
  15. @login_required
  16. @account_initialization_required
  17. def get(self):
  18. user = current_user
  19. if not user.is_admin_or_owner:
  20. raise Forbidden()
  21. tenant_id = user.current_tenant_id
  22. return {
  23. "key": PluginService.get_debugging_key(tenant_id),
  24. "host": dify_config.PLUGIN_REMOTE_INSTALL_HOST,
  25. "port": dify_config.PLUGIN_REMOTE_INSTALL_PORT,
  26. }
  27. class PluginListApi(Resource):
  28. @setup_required
  29. @login_required
  30. @account_initialization_required
  31. def get(self):
  32. user = current_user
  33. tenant_id = user.current_tenant_id
  34. plugins = PluginService.list(tenant_id)
  35. return jsonable_encoder({"plugins": plugins})
  36. class PluginIconApi(Resource):
  37. @setup_required
  38. def get(self):
  39. req = reqparse.RequestParser()
  40. req.add_argument("tenant_id", type=str, required=True, location="args")
  41. req.add_argument("filename", type=str, required=True, location="args")
  42. args = req.parse_args()
  43. icon_bytes, mimetype = PluginService.get_asset(args["tenant_id"], args["filename"])
  44. icon_cache_max_age = dify_config.TOOL_ICON_CACHE_MAX_AGE
  45. return send_file(io.BytesIO(icon_bytes), mimetype=mimetype, max_age=icon_cache_max_age)
  46. class PluginUploadPkgApi(Resource):
  47. @setup_required
  48. @login_required
  49. @account_initialization_required
  50. def post(self):
  51. user = current_user
  52. if not user.is_admin_or_owner:
  53. raise Forbidden()
  54. tenant_id = user.current_tenant_id
  55. file = request.files["pkg"]
  56. content = file.read()
  57. return {"plugin_unique_identifier": PluginService.upload_pkg(tenant_id, content)}
  58. class PluginUploadFromPkgApi(Resource):
  59. @setup_required
  60. @login_required
  61. @account_initialization_required
  62. def post(self):
  63. user = current_user
  64. if not user.is_admin_or_owner:
  65. raise Forbidden()
  66. tenant_id = user.current_tenant_id
  67. file = request.files["pkg"]
  68. content = file.read()
  69. response = PluginService.upload_pkg(tenant_id, content)
  70. return {
  71. "plugin_unique_identifier": response,
  72. }
  73. class PluginUploadFromGithubApi(Resource):
  74. @setup_required
  75. @login_required
  76. @account_initialization_required
  77. def post(self):
  78. user = current_user
  79. if not user.is_admin_or_owner:
  80. raise Forbidden()
  81. tenant_id = user.current_tenant_id
  82. parser = reqparse.RequestParser()
  83. parser.add_argument("repo", type=str, required=True, location="json")
  84. parser.add_argument("version", type=str, required=True, location="json")
  85. parser.add_argument("package", type=str, required=True, location="json")
  86. args = parser.parse_args()
  87. response = PluginService.upload_pkg_from_github(tenant_id, args["repo"], args["version"], args["package"])
  88. return {
  89. "plugin_unique_identifier": response,
  90. }
  91. class PluginInstallFromPkgApi(Resource):
  92. @setup_required
  93. @login_required
  94. @account_initialization_required
  95. def post(self):
  96. user = current_user
  97. if not user.is_admin_or_owner:
  98. raise Forbidden()
  99. tenant_id = user.current_tenant_id
  100. parser = reqparse.RequestParser()
  101. parser.add_argument("plugin_unique_identifier", type=str, required=True, location="json")
  102. args = parser.parse_args()
  103. response = PluginService.install_from_local_pkg(tenant_id, args["plugin_unique_identifier"])
  104. return {
  105. "task_id": response,
  106. }
  107. class PluginInstallFromGithubApi(Resource):
  108. @setup_required
  109. @login_required
  110. @account_initialization_required
  111. def post(self):
  112. user = current_user
  113. if not user.is_admin_or_owner:
  114. raise Forbidden()
  115. tenant_id = user.current_tenant_id
  116. parser = reqparse.RequestParser()
  117. parser.add_argument("repo", type=str, required=True, location="json")
  118. parser.add_argument("version", type=str, required=True, location="json")
  119. parser.add_argument("package", type=str, required=True, location="json")
  120. parser.add_argument("plugin_unique_identifier", type=str, required=True, location="json")
  121. args = parser.parse_args()
  122. response = PluginService.install_from_github(
  123. tenant_id, args["repo"], args["version"], args["package"], args["plugin_unique_identifier"]
  124. )
  125. return {
  126. "task_id": response,
  127. }
  128. class PluginInstallFromMarketplaceApi(Resource):
  129. @setup_required
  130. @login_required
  131. @account_initialization_required
  132. def post(self):
  133. user = current_user
  134. if not user.is_admin_or_owner:
  135. raise Forbidden()
  136. tenant_id = user.current_tenant_id
  137. parser = reqparse.RequestParser()
  138. parser.add_argument("plugin_unique_identifier", type=str, required=True, location="json")
  139. args = parser.parse_args()
  140. response = PluginService.install_from_marketplace_pkg(tenant_id, args["plugin_unique_identifier"])
  141. return {
  142. "task_id": response,
  143. }
  144. class PluginFetchManifestApi(Resource):
  145. @setup_required
  146. @login_required
  147. @account_initialization_required
  148. def get(self):
  149. user = current_user
  150. parser = reqparse.RequestParser()
  151. parser.add_argument("plugin_unique_identifier", type=str, required=True, location="args")
  152. args = parser.parse_args()
  153. tenant_id = user.current_tenant_id
  154. return {"manifest": PluginService.fetch_plugin_manifest(tenant_id, args["plugin_unique_identifier"])}
  155. class PluginFetchInstallTasksApi(Resource):
  156. @setup_required
  157. @login_required
  158. @account_initialization_required
  159. def get(self):
  160. user = current_user
  161. if not user.is_admin_or_owner:
  162. raise Forbidden()
  163. tenant_id = user.current_tenant_id
  164. return {"tasks": PluginService.fetch_install_tasks(tenant_id)}
  165. class PluginFetchInstallTaskApi(Resource):
  166. @setup_required
  167. @login_required
  168. @account_initialization_required
  169. def get(self, task_id: str):
  170. user = current_user
  171. if not user.is_admin_or_owner:
  172. raise Forbidden()
  173. tenant_id = user.current_tenant_id
  174. return {"task": PluginService.fetch_install_task(tenant_id, task_id)}
  175. class PluginUninstallApi(Resource):
  176. @setup_required
  177. @login_required
  178. @account_initialization_required
  179. def post(self):
  180. req = reqparse.RequestParser()
  181. req.add_argument("plugin_installation_id", type=str, required=True, location="json")
  182. args = req.parse_args()
  183. user = current_user
  184. if not user.is_admin_or_owner:
  185. raise Forbidden()
  186. tenant_id = user.current_tenant_id
  187. return {"success": PluginService.uninstall(tenant_id, args["plugin_installation_id"])}
  188. api.add_resource(PluginDebuggingKeyApi, "/workspaces/current/plugin/debugging-key")
  189. api.add_resource(PluginListApi, "/workspaces/current/plugin/list")
  190. api.add_resource(PluginIconApi, "/workspaces/current/plugin/icon")
  191. api.add_resource(PluginUploadFromPkgApi, "/workspaces/current/plugin/upload/pkg")
  192. api.add_resource(PluginUploadFromGithubApi, "/workspaces/current/plugin/upload/github")
  193. api.add_resource(PluginInstallFromPkgApi, "/workspaces/current/plugin/install/pkg")
  194. api.add_resource(PluginInstallFromGithubApi, "/workspaces/current/plugin/install/github")
  195. api.add_resource(PluginInstallFromMarketplaceApi, "/workspaces/current/plugin/install/marketplace")
  196. api.add_resource(PluginFetchManifestApi, "/workspaces/current/plugin/fetch-manifest")
  197. api.add_resource(PluginFetchInstallTasksApi, "/workspaces/current/plugin/tasks")
  198. api.add_resource(PluginFetchInstallTaskApi, "/workspaces/current/plugin/tasks/<task_id>")
  199. api.add_resource(PluginUninstallApi, "/workspaces/current/plugin/uninstall")