Skip to content

Commit c506a23

Browse files
committed
feat: add StoreKnowledge API to fetch Appstore tools and update routing
1 parent 903ad0e commit c506a23

File tree

4 files changed

+74
-3
lines changed

4 files changed

+74
-3
lines changed

apps/knowledge/serializers/knowledge.py

Lines changed: 53 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,15 @@
22
import json
33
import os
44
import re
5+
import tempfile
56
import traceback
7+
import zipfile
68
from collections import defaultdict
79
from functools import reduce
810
from tempfile import TemporaryDirectory
911
from typing import Dict, List
1012

13+
import requests
1114
import uuid_utils.compat as uuid
1215
from celery_once import AlreadyQueued
1316
from django.core import validators
@@ -19,7 +22,6 @@
1922
from django.utils.translation import gettext_lazy as _
2023
from rest_framework import serializers
2124

22-
from application.flow.tools import get_workflow_resource, get_node_handle_callback, save_workflow_mapping
2325
from application.models import ApplicationKnowledgeMapping
2426
from common.config.embedding_config import VectorStore
2527
from common.database_model_manage.database_model_manage import DatabaseModelManage
@@ -32,7 +34,7 @@
3234
from common.utils.logger import maxkb_logger
3335
from common.utils.split_model import get_split_model
3436
from knowledge.models import Knowledge, KnowledgeScope, KnowledgeType, Document, Paragraph, Problem, \
35-
ProblemParagraphMapping, TaskType, State, SearchMode, KnowledgeFolder, File, Tag, KnowledgeWorkflow
37+
ProblemParagraphMapping, TaskType, State, SearchMode, KnowledgeFolder, File, Tag
3638
from knowledge.serializers.common import ProblemParagraphManage, drop_knowledge_index, \
3739
get_embedding_model_id_by_knowledge_id, MetaSerializer, \
3840
GenerateRelatedSerializer, get_embedding_model_by_knowledge_id, list_paragraph, write_image, zip_dir, \
@@ -44,7 +46,6 @@
4446
from maxkb.conf import PROJECT_DIR
4547
from models_provider.models import Model
4648
from system_manage.models import WorkspaceUserResourcePermission, AuthTargetType
47-
from system_manage.models.resource_mapping import ResourceType, ResourceMapping
4849
from system_manage.serializers.user_resource_permission import UserResourcePermissionSerializer
4950
from users.serializers.user import is_workspace_manage
5051

@@ -768,6 +769,55 @@ def hit_test(self):
768769
} for p in p_list
769770
]
770771

772+
class StoreKnowledge(serializers.Serializer):
773+
user_id = serializers.UUIDField(required=True, label=_("User ID"))
774+
name = serializers.CharField(required=False, label=_("tool name"), allow_null=True, allow_blank=True)
775+
776+
def get_appstore_templates(self):
777+
self.is_valid(raise_exception=True)
778+
# 下载zip文件
779+
try:
780+
res = requests.get('https://apps-assets.fit2cloud.com/stable/maxkb.json.zip', timeout=5)
781+
res.raise_for_status()
782+
# 创建临时文件保存zip
783+
with tempfile.NamedTemporaryFile(delete=False, suffix='.zip') as temp_zip:
784+
temp_zip.write(res.content)
785+
temp_zip_path = temp_zip.name
786+
787+
try:
788+
# 解压zip文件
789+
with zipfile.ZipFile(temp_zip_path, 'r') as zip_ref:
790+
# 获取zip中的第一个文件(假设只有一个json文件)
791+
json_filename = zip_ref.namelist()[0]
792+
json_content = zip_ref.read(json_filename)
793+
794+
# 将json转换为字典
795+
tool_store = json.loads(json_content.decode('utf-8'))
796+
tag_dict = {tag['name']: tag['key'] for tag in tool_store['additionalProperties']['tags']}
797+
filter_apps = []
798+
for tool in tool_store['apps']:
799+
if self.data.get('name', '') != '':
800+
if self.data.get('name').lower() not in tool.get('name', '').lower():
801+
continue
802+
if not tool['downloadUrl'].endswith('.kbwf'):
803+
continue
804+
versions = tool.get('versions', [])
805+
tool['label'] = tag_dict[tool.get('tags')[0]] if tool.get('tags') else ''
806+
tool['version'] = next(
807+
(version.get('name') for version in versions if
808+
version.get('downloadUrl') == tool['downloadUrl']),
809+
)
810+
filter_apps.append(tool)
811+
812+
tool_store['apps'] = filter_apps
813+
return tool_store
814+
finally:
815+
# 清理临时文件
816+
os.unlink(temp_zip_path)
817+
except Exception as e:
818+
maxkb_logger.error(f"fetch appstore tools error: {e}")
819+
return {'apps': [], 'additionalProperties': {'tags': []}}
820+
771821
class Tags(serializers.Serializer):
772822
workspace_id = serializers.CharField(required=True, label=_('workspace id'))
773823
user_id = serializers.UUIDField(required=True, label=_('user id'))

apps/knowledge/urls.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
urlpatterns = [
88
path('workspace/knowledge/document/template/export', views.Template.as_view()),
99
path('workspace/knowledge/document/table_template/export', views.TableTemplate.as_view()),
10+
path('workspace/store/knowledge_template', views.KnowledgeView.StoreKnowledge.as_view()),
1011
path('workspace/<str:workspace_id>/knowledge', views.KnowledgeView.as_view()),
1112
path('workspace/<str:workspace_id>/knowledge/base', views.KnowledgeBaseView.as_view()),
1213
path('workspace/<str:workspace_id>/knowledge/workflow', views.KnowledgeWorkflowView.as_view()),

apps/knowledge/views/knowledge.py

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
from knowledge.serializers.common import get_knowledge_operation_object
1616
from knowledge.serializers.knowledge import KnowledgeSerializer
1717
from models_provider.serializers.model_serializer import ModelSerializer
18+
from tools.api.tool import GetInternalToolAPI
1819

1920

2021
class KnowledgeView(APIView):
@@ -220,6 +221,23 @@ def put(self, request: Request, workspace_id: str, knowledge_id: str):
220221
}
221222
).hit_test())
222223

224+
class StoreKnowledge(APIView):
225+
authentication_classes = [TokenAuth]
226+
227+
@extend_schema(
228+
methods=['GET'],
229+
description=_("Get Appstore tools"),
230+
summary=_("Get Appstore tools"),
231+
operation_id=_("Get Appstore tools"), # type: ignore
232+
responses=GetInternalToolAPI.get_response(),
233+
tags=[_("Tool")] # type: ignore
234+
)
235+
def get(self, request: Request):
236+
return result.success(KnowledgeSerializer.StoreKnowledge(data={
237+
'user_id': request.user.id,
238+
'name': request.query_params.get('name', ''),
239+
}).get_appstore_templates())
240+
223241
class Embedding(APIView):
224242
authentication_classes = [TokenAuth]
225243

apps/tools/serializers/tool.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -761,6 +761,8 @@ def get_appstore_tools(self):
761761
if self.data.get('name', '') != '':
762762
if self.data.get('name').lower() not in tool.get('name', '').lower():
763763
continue
764+
if not tool['downloadUrl'].endswith('.tool'):
765+
continue
764766
versions = tool.get('versions', [])
765767
tool['label'] = tag_dict[tool.get('tags')[0]] if tool.get('tags') else ''
766768
tool['version'] = next(

0 commit comments

Comments
 (0)