mirror of
https://github.com/langgenius/dify.git
synced 2026-04-27 19:19:06 +08:00
feat: support install plugin
This commit is contained in:
parent
2223dfb266
commit
eef79a5196
@ -56,4 +56,13 @@ from .explore import (
|
|||||||
from .tag import tags
|
from .tag import tags
|
||||||
|
|
||||||
# Import workspace controllers
|
# Import workspace controllers
|
||||||
from .workspace import account, load_balancing_config, members, model_providers, models, tool_providers, workspace, plugin
|
from .workspace import (
|
||||||
|
account,
|
||||||
|
load_balancing_config,
|
||||||
|
members,
|
||||||
|
model_providers,
|
||||||
|
models,
|
||||||
|
plugin,
|
||||||
|
tool_providers,
|
||||||
|
workspace,
|
||||||
|
)
|
||||||
|
|||||||
@ -1,8 +1,9 @@
|
|||||||
|
from enum import Enum
|
||||||
from typing import Generic, Optional, TypeVar
|
from typing import Generic, Optional, TypeVar
|
||||||
|
|
||||||
from pydantic import BaseModel
|
from pydantic import BaseModel
|
||||||
|
|
||||||
T = TypeVar("T", bound=(BaseModel | dict))
|
T = TypeVar("T", bound=(BaseModel | dict | bool))
|
||||||
|
|
||||||
|
|
||||||
class PluginDaemonBasicResponse(BaseModel, Generic[T]):
|
class PluginDaemonBasicResponse(BaseModel, Generic[T]):
|
||||||
@ -13,3 +14,16 @@ class PluginDaemonBasicResponse(BaseModel, Generic[T]):
|
|||||||
code: int
|
code: int
|
||||||
message: str
|
message: str
|
||||||
data: Optional[T]
|
data: Optional[T]
|
||||||
|
|
||||||
|
|
||||||
|
class InstallPluginMessage(BaseModel):
|
||||||
|
"""
|
||||||
|
Message for installing a plugin.
|
||||||
|
"""
|
||||||
|
class Event(Enum):
|
||||||
|
Info = "info"
|
||||||
|
Done = "done"
|
||||||
|
Error = "error"
|
||||||
|
|
||||||
|
event: Event
|
||||||
|
data: str
|
||||||
@ -12,12 +12,17 @@ from core.plugin.entities.plugin_daemon import PluginDaemonBasicResponse
|
|||||||
plugin_daemon_inner_api_baseurl = dify_config.PLUGIN_API_URL
|
plugin_daemon_inner_api_baseurl = dify_config.PLUGIN_API_URL
|
||||||
plugin_daemon_inner_api_key = dify_config.PLUGIN_API_KEY
|
plugin_daemon_inner_api_key = dify_config.PLUGIN_API_KEY
|
||||||
|
|
||||||
T = TypeVar("T", bound=(BaseModel | dict))
|
T = TypeVar("T", bound=(BaseModel | dict | bool))
|
||||||
|
|
||||||
|
|
||||||
class BasePluginManager:
|
class BasePluginManager:
|
||||||
def _request(
|
def _request(
|
||||||
self, method: str, path: str, headers: dict | None = None, data: bytes | None = None, stream: bool = False
|
self,
|
||||||
|
method: str,
|
||||||
|
path: str,
|
||||||
|
headers: dict | None = None,
|
||||||
|
data: bytes | dict | None = None,
|
||||||
|
stream: bool = False,
|
||||||
) -> requests.Response:
|
) -> requests.Response:
|
||||||
"""
|
"""
|
||||||
Make a request to the plugin daemon inner API.
|
Make a request to the plugin daemon inner API.
|
||||||
@ -29,7 +34,7 @@ class BasePluginManager:
|
|||||||
return response
|
return response
|
||||||
|
|
||||||
def _stream_request(
|
def _stream_request(
|
||||||
self, method: str, path: str, headers: dict | None = None, data: bytes | None = None
|
self, method: str, path: str, headers: dict | None = None, data: bytes | dict | None = None
|
||||||
) -> Generator[bytes, None, None]:
|
) -> Generator[bytes, None, None]:
|
||||||
"""
|
"""
|
||||||
Make a stream request to the plugin daemon inner API
|
Make a stream request to the plugin daemon inner API
|
||||||
@ -43,7 +48,7 @@ class BasePluginManager:
|
|||||||
path: str,
|
path: str,
|
||||||
type: type[T],
|
type: type[T],
|
||||||
headers: dict | None = None,
|
headers: dict | None = None,
|
||||||
data: bytes | None = None,
|
data: bytes | dict | None = None,
|
||||||
) -> Generator[T, None, None]:
|
) -> Generator[T, None, None]:
|
||||||
"""
|
"""
|
||||||
Make a stream request to the plugin daemon inner API and yield the response as a model.
|
Make a stream request to the plugin daemon inner API and yield the response as a model.
|
||||||
@ -61,7 +66,7 @@ class BasePluginManager:
|
|||||||
return type(**response.json())
|
return type(**response.json())
|
||||||
|
|
||||||
def _request_with_plugin_daemon_response(
|
def _request_with_plugin_daemon_response(
|
||||||
self, method: str, path: str, type: type[T], headers: dict | None = None, data: bytes | None = None
|
self, method: str, path: str, type: type[T], headers: dict | None = None, data: bytes | dict | None = None
|
||||||
) -> T:
|
) -> T:
|
||||||
"""
|
"""
|
||||||
Make a request to the plugin daemon inner API and return the response as a model.
|
Make a request to the plugin daemon inner API and return the response as a model.
|
||||||
@ -72,11 +77,11 @@ class BasePluginManager:
|
|||||||
raise ValueError(f"got error from plugin daemon: {rep.message}, code: {rep.code}")
|
raise ValueError(f"got error from plugin daemon: {rep.message}, code: {rep.code}")
|
||||||
if rep.data is None:
|
if rep.data is None:
|
||||||
raise ValueError("got empty data from plugin daemon")
|
raise ValueError("got empty data from plugin daemon")
|
||||||
|
|
||||||
return rep.data
|
return rep.data
|
||||||
|
|
||||||
def _request_with_plugin_daemon_response_stream(
|
def _request_with_plugin_daemon_response_stream(
|
||||||
self, method: str, path: str, type: type[T], headers: dict | None = None, data: bytes | None = None
|
self, method: str, path: str, type: type[T], headers: dict | None = None, data: bytes | dict | None = None
|
||||||
) -> Generator[T, None, None]:
|
) -> Generator[T, None, None]:
|
||||||
"""
|
"""
|
||||||
Make a stream request to the plugin daemon inner API and yield the response as a model.
|
Make a stream request to the plugin daemon inner API and yield the response as a model.
|
||||||
@ -85,7 +90,7 @@ class BasePluginManager:
|
|||||||
line_data = json.loads(line)
|
line_data = json.loads(line)
|
||||||
rep = PluginDaemonBasicResponse[type](**line_data)
|
rep = PluginDaemonBasicResponse[type](**line_data)
|
||||||
if rep.code != 0:
|
if rep.code != 0:
|
||||||
raise Exception(f"got error from plugin daemon: {rep.message}, code: {rep.code}")
|
raise ValueError(f"got error from plugin daemon: {rep.message}, code: {rep.code}")
|
||||||
if rep.data is None:
|
if rep.data is None:
|
||||||
raise Exception("got empty data from plugin daemon")
|
raise ValueError("got empty data from plugin daemon")
|
||||||
yield rep.data
|
yield rep.data
|
||||||
|
|||||||
46
api/core/plugin/manager/plugin.py
Normal file
46
api/core/plugin/manager/plugin.py
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
from collections.abc import Generator
|
||||||
|
from urllib.parse import quote
|
||||||
|
|
||||||
|
from core.plugin.entities.plugin_daemon import InstallPluginMessage
|
||||||
|
from core.plugin.manager.base import BasePluginManager
|
||||||
|
|
||||||
|
|
||||||
|
class PluginInstallationManager(BasePluginManager):
|
||||||
|
def fetch_plugin_by_identifier(self, tenant_id: str, identifier: str) -> bool:
|
||||||
|
# urlencode the identifier
|
||||||
|
|
||||||
|
identifier = quote(identifier)
|
||||||
|
return self._request_with_plugin_daemon_response(
|
||||||
|
"GET", f"/plugin/{tenant_id}/fetch/identifier?plugin_unique_identifier={identifier}", bool
|
||||||
|
)
|
||||||
|
|
||||||
|
def install_from_pkg(self, tenant_id: str, pkg: bytes) -> Generator[InstallPluginMessage, None, None]:
|
||||||
|
"""
|
||||||
|
Install a plugin from a package.
|
||||||
|
"""
|
||||||
|
# using multipart/form-data to encode body
|
||||||
|
body = {"dify_pkg": ("dify_pkg", pkg, "application/octet-stream")}
|
||||||
|
|
||||||
|
return self._request_with_plugin_daemon_response_stream(
|
||||||
|
"POST", f"/plugin/{tenant_id}/install/pkg", InstallPluginMessage, data=body
|
||||||
|
)
|
||||||
|
|
||||||
|
def install_from_identifier(self, tenant_id: str, identifier: str) -> bool:
|
||||||
|
"""
|
||||||
|
Install a plugin from an identifier.
|
||||||
|
"""
|
||||||
|
identifier = quote(identifier)
|
||||||
|
# exception will be raised if the request failed
|
||||||
|
self._request_with_plugin_daemon_response(
|
||||||
|
"POST",
|
||||||
|
f"/plugin/{tenant_id}/install/identifier",
|
||||||
|
dict,
|
||||||
|
headers={
|
||||||
|
"Content-Type": "application/json",
|
||||||
|
},
|
||||||
|
data={
|
||||||
|
"plugin_unique_identifier": identifier,
|
||||||
|
},
|
||||||
|
)
|
||||||
|
|
||||||
|
return True
|
||||||
Loading…
Reference in New Issue
Block a user