mirror of
https://github.com/langgenius/dify.git
synced 2025-12-20 14:42:37 +00:00
Compare commits
2 Commits
fix/docume
...
feat/plugi
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
94ecbd44e4 | ||
|
|
ba76312248 |
@@ -107,6 +107,22 @@ class PluginIconApi(Resource):
|
|||||||
icon_cache_max_age = dify_config.TOOL_ICON_CACHE_MAX_AGE
|
icon_cache_max_age = dify_config.TOOL_ICON_CACHE_MAX_AGE
|
||||||
return send_file(io.BytesIO(icon_bytes), mimetype=mimetype, max_age=icon_cache_max_age)
|
return send_file(io.BytesIO(icon_bytes), mimetype=mimetype, max_age=icon_cache_max_age)
|
||||||
|
|
||||||
|
class PluginAssetApi(Resource):
|
||||||
|
@setup_required
|
||||||
|
@login_required
|
||||||
|
@account_initialization_required
|
||||||
|
def get(self):
|
||||||
|
req = reqparse.RequestParser()
|
||||||
|
req.add_argument("plugin_unique_identifier", type=str, required=True, location="args")
|
||||||
|
req.add_argument("file_name", type=str, required=True, location="args")
|
||||||
|
args = req.parse_args()
|
||||||
|
|
||||||
|
tenant_id = current_user.current_tenant_id
|
||||||
|
try:
|
||||||
|
binary = PluginService.extract_asset(tenant_id, args["plugin_unique_identifier"], args["file_name"])
|
||||||
|
return send_file(io.BytesIO(binary), mimetype="application/octet-stream")
|
||||||
|
except PluginDaemonClientSideError as e:
|
||||||
|
raise ValueError(e)
|
||||||
|
|
||||||
class PluginUploadFromPkgApi(Resource):
|
class PluginUploadFromPkgApi(Resource):
|
||||||
@setup_required
|
@setup_required
|
||||||
@@ -643,11 +659,34 @@ class PluginAutoUpgradeExcludePluginApi(Resource):
|
|||||||
return jsonable_encoder({"success": PluginAutoUpgradeService.exclude_plugin(tenant_id, args["plugin_id"])})
|
return jsonable_encoder({"success": PluginAutoUpgradeService.exclude_plugin(tenant_id, args["plugin_id"])})
|
||||||
|
|
||||||
|
|
||||||
|
class PluginReadmeApi(Resource):
|
||||||
|
@setup_required
|
||||||
|
@login_required
|
||||||
|
@account_initialization_required
|
||||||
|
def get(self):
|
||||||
|
tenant_id = current_user.current_tenant_id
|
||||||
|
parser = reqparse.RequestParser()
|
||||||
|
parser.add_argument("plugin_unique_identifier", type=str, required=True, location="args")
|
||||||
|
parser.add_argument("language", type=str, required=False, location="args")
|
||||||
|
args = parser.parse_args()
|
||||||
|
return jsonable_encoder(
|
||||||
|
{
|
||||||
|
"readme": PluginService.fetch_plugin_readme(
|
||||||
|
tenant_id,
|
||||||
|
args["plugin_unique_identifier"],
|
||||||
|
args.get("language", "en-US")
|
||||||
|
)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
api.add_resource(PluginDebuggingKeyApi, "/workspaces/current/plugin/debugging-key")
|
api.add_resource(PluginDebuggingKeyApi, "/workspaces/current/plugin/debugging-key")
|
||||||
api.add_resource(PluginListApi, "/workspaces/current/plugin/list")
|
api.add_resource(PluginListApi, "/workspaces/current/plugin/list")
|
||||||
|
api.add_resource(PluginReadmeApi, "/workspaces/current/plugin/readme")
|
||||||
api.add_resource(PluginListLatestVersionsApi, "/workspaces/current/plugin/list/latest-versions")
|
api.add_resource(PluginListLatestVersionsApi, "/workspaces/current/plugin/list/latest-versions")
|
||||||
api.add_resource(PluginListInstallationsFromIdsApi, "/workspaces/current/plugin/list/installations/ids")
|
api.add_resource(PluginListInstallationsFromIdsApi, "/workspaces/current/plugin/list/installations/ids")
|
||||||
api.add_resource(PluginIconApi, "/workspaces/current/plugin/icon")
|
api.add_resource(PluginIconApi, "/workspaces/current/plugin/icon")
|
||||||
|
api.add_resource(PluginAssetApi, "/workspaces/current/plugin/asset")
|
||||||
api.add_resource(PluginUploadFromPkgApi, "/workspaces/current/plugin/upload/pkg")
|
api.add_resource(PluginUploadFromPkgApi, "/workspaces/current/plugin/upload/pkg")
|
||||||
api.add_resource(PluginUploadFromGithubApi, "/workspaces/current/plugin/upload/github")
|
api.add_resource(PluginUploadFromGithubApi, "/workspaces/current/plugin/upload/github")
|
||||||
api.add_resource(PluginUploadFromBundleApi, "/workspaces/current/plugin/upload/bundle")
|
api.add_resource(PluginUploadFromBundleApi, "/workspaces/current/plugin/upload/bundle")
|
||||||
|
|||||||
@@ -196,3 +196,7 @@ class PluginListResponse(BaseModel):
|
|||||||
|
|
||||||
class PluginDynamicSelectOptionsResponse(BaseModel):
|
class PluginDynamicSelectOptionsResponse(BaseModel):
|
||||||
options: Sequence[PluginParameterOption] = Field(description="The options of the dynamic select.")
|
options: Sequence[PluginParameterOption] = Field(description="The options of the dynamic select.")
|
||||||
|
|
||||||
|
class PluginReadmeResponse(BaseModel):
|
||||||
|
content: str = Field(description="The readme of the plugin.")
|
||||||
|
language: str = Field(description="The language of the readme.")
|
||||||
|
|||||||
@@ -10,3 +10,9 @@ class PluginAssetManager(BasePluginClient):
|
|||||||
if response.status_code != 200:
|
if response.status_code != 200:
|
||||||
raise ValueError(f"can not found asset {id}")
|
raise ValueError(f"can not found asset {id}")
|
||||||
return response.content
|
return response.content
|
||||||
|
|
||||||
|
def extract_asset(self, tenant_id: str, plugin_unique_identifier: str, filename: str) -> bytes:
|
||||||
|
response = self._request(method="GET", path=f"plugin/{tenant_id}/asset/{plugin_unique_identifier}")
|
||||||
|
if response.status_code != 200:
|
||||||
|
raise ValueError(f"can not found asset {plugin_unique_identifier}, {str(response.status_code)}")
|
||||||
|
return response.content
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
from collections.abc import Sequence
|
from collections.abc import Sequence
|
||||||
|
|
||||||
|
from requests import HTTPError
|
||||||
|
|
||||||
from core.plugin.entities.bundle import PluginBundleDependency
|
from core.plugin.entities.bundle import PluginBundleDependency
|
||||||
from core.plugin.entities.plugin import (
|
from core.plugin.entities.plugin import (
|
||||||
GenericProviderID,
|
GenericProviderID,
|
||||||
@@ -14,11 +16,34 @@ from core.plugin.entities.plugin_daemon import (
|
|||||||
PluginInstallTask,
|
PluginInstallTask,
|
||||||
PluginInstallTaskStartResponse,
|
PluginInstallTaskStartResponse,
|
||||||
PluginListResponse,
|
PluginListResponse,
|
||||||
|
PluginReadmeResponse,
|
||||||
)
|
)
|
||||||
from core.plugin.impl.base import BasePluginClient
|
from core.plugin.impl.base import BasePluginClient
|
||||||
|
|
||||||
|
|
||||||
class PluginInstaller(BasePluginClient):
|
class PluginInstaller(BasePluginClient):
|
||||||
|
def fetch_plugin_readme(self, tenant_id: str, plugin_unique_identifier: str, language: str) -> str:
|
||||||
|
"""
|
||||||
|
Fetch plugin readme
|
||||||
|
"""
|
||||||
|
try:
|
||||||
|
response = self._request_with_plugin_daemon_response(
|
||||||
|
"GET",
|
||||||
|
f"plugin/{tenant_id}/management/fetch/readme",
|
||||||
|
PluginReadmeResponse,
|
||||||
|
params={
|
||||||
|
"tenant_id":tenant_id,
|
||||||
|
"plugin_unique_identifier": plugin_unique_identifier,
|
||||||
|
"language": language
|
||||||
|
}
|
||||||
|
)
|
||||||
|
return response.content
|
||||||
|
except HTTPError as e:
|
||||||
|
message = e.args[0]
|
||||||
|
if "404" in message:
|
||||||
|
return ""
|
||||||
|
raise e
|
||||||
|
|
||||||
def fetch_plugin_by_identifier(
|
def fetch_plugin_by_identifier(
|
||||||
self,
|
self,
|
||||||
tenant_id: str,
|
tenant_id: str,
|
||||||
|
|||||||
@@ -186,6 +186,11 @@ class PluginService:
|
|||||||
mime_type, _ = guess_type(asset_file)
|
mime_type, _ = guess_type(asset_file)
|
||||||
return manager.fetch_asset(tenant_id, asset_file), mime_type or "application/octet-stream"
|
return manager.fetch_asset(tenant_id, asset_file), mime_type or "application/octet-stream"
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def extract_asset(tenant_id: str, plugin_unique_identifier: str, file_name: str) -> bytes:
|
||||||
|
manager = PluginAssetManager()
|
||||||
|
return manager.extract_asset(tenant_id, plugin_unique_identifier, file_name)
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def check_plugin_unique_identifier(tenant_id: str, plugin_unique_identifier: str) -> bool:
|
def check_plugin_unique_identifier(tenant_id: str, plugin_unique_identifier: str) -> bool:
|
||||||
"""
|
"""
|
||||||
@@ -492,3 +497,11 @@ class PluginService:
|
|||||||
"""
|
"""
|
||||||
manager = PluginInstaller()
|
manager = PluginInstaller()
|
||||||
return manager.check_tools_existence(tenant_id, provider_ids)
|
return manager.check_tools_existence(tenant_id, provider_ids)
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def fetch_plugin_readme(tenant_id: str, plugin_unique_identifier: str, language: str) -> str:
|
||||||
|
"""
|
||||||
|
Fetch plugin readme
|
||||||
|
"""
|
||||||
|
manager = PluginInstaller()
|
||||||
|
return manager.fetch_plugin_readme(tenant_id, plugin_unique_identifier, language)
|
||||||
|
|||||||
Reference in New Issue
Block a user