From 3bb00251334ec12024c5b77f336002ac0b1603a7 Mon Sep 17 00:00:00 2001 From: wxg0103 <727495428@qq.com> Date: Thu, 5 Nov 2026 14:20:48 +0800 Subject: [PATCH] chore: update community identifier and enhance serializers for system API key and shared model responses --- apps/chat/views/v2/chat.py | 12 +- apps/chat/views/v2/chat_record.py | 19 ++- apps/chat/views/v3/chat.py | 12 +- apps/chat/views/v3/chat_user_api_key.py | 20 ++- apps/common/result/api.py | 65 +++++--- apps/models_provider/api/model.py | 82 +++++++++- apps/models_provider/api/provide.py | 2 +- .../serializers/model_serializer.py | 18 ++- apps/models_provider/views/model.py | 17 +- apps/trigger/api/trigger.py | 92 ++++++----- apps/trigger/api/trigger_task.py | 73 +++++---- apps/users/api/user.py | 152 ++++++++++-------- 12 files changed, 378 insertions(+), 186 deletions(-) diff --git a/apps/chat/views/v2/chat.py b/apps/chat/views/v2/chat.py index f19b3c25130..151bd284a10 100644 --- a/apps/chat/views/v2/chat.py +++ b/apps/chat/views/v2/chat.py @@ -13,7 +13,7 @@ from django.core.cache import cache from django.http import HttpResponse, StreamingHttpResponse from django.utils.translation import gettext_lazy as _ -from drf_spectacular.utils import extend_schema +from drf_spectacular.utils import OpenApiResponse, extend_schema from drf_spectacular.types import OpenApiTypes from drf_spectacular.utils import OpenApiParameter from rest_framework.parsers import MultiPartParser @@ -46,7 +46,7 @@ from common.constants.cache_version import Cache_Version from common.exception.app_exception import AppAuthenticationFailed, AppApiException from common.log.log import _get_ip_address, log -from common.result import result +from common.result import DefaultResultSerializer, result from common.utils.rsa_util import decrypt from knowledge.models import FileSourceType from maxkb.const import CONFIG @@ -238,7 +238,13 @@ class OpenView(APIView): summary=_("Get the session id according to the application id"), operation_id=_("Get the session id according to the application id"), # type: ignore parameters=ChatOpenAPI.get_parameters(), - responses=None, + responses={ + 200: None, + 401: OpenApiResponse( + response=DefaultResultSerializer, + description=_("Authentication required"), + ), + }, tags=[_("Chat")], # type: ignore ) @has_permissions(ChatPermissionConstants.get_aggregate_permissions()) diff --git a/apps/chat/views/v2/chat_record.py b/apps/chat/views/v2/chat_record.py index 38456f977ef..b8a22c20a24 100644 --- a/apps/chat/views/v2/chat_record.py +++ b/apps/chat/views/v2/chat_record.py @@ -8,7 +8,7 @@ """ from django.utils.translation import gettext_lazy as _ -from drf_spectacular.utils import extend_schema +from drf_spectacular.utils import OpenApiResponse, extend_schema from rest_framework.request import Request from rest_framework.views import APIView @@ -29,6 +29,7 @@ ) from common import result from common.auth import ChatTokenAuth +from common.result import DefaultResultSerializer class VoteView(APIView): @@ -65,7 +66,13 @@ class HistoricalConversationView(APIView): summary=_("Get historical conversation"), operation_id=_("Get historical conversation"), # type: ignore parameters=HistoricalConversationAPI.get_parameters(), - responses=HistoricalConversationAPI.get_response(), + responses={ + 200: HistoricalConversationAPI.get_response(), + 401: OpenApiResponse( + response=DefaultResultSerializer, + description=_("Authentication required"), + ), + }, tags=[_("Chat")], # type: ignore ) def get(self, request: Request): @@ -153,7 +160,13 @@ class PageView(APIView): summary=_("Get historical conversation by page"), operation_id=_("Get historical conversation by page"), # type: ignore parameters=PageHistoricalConversationAPI.get_parameters(), - responses=PageHistoricalConversationAPI.get_response(), + responses={ + 200: PageHistoricalConversationAPI.get_response(), + 401: OpenApiResponse( + response=DefaultResultSerializer, + description=_("Authentication required"), + ), + }, tags=[_("Chat")], # type: ignore ) def get(self, request: Request, current_page: int, page_size: int): diff --git a/apps/chat/views/v3/chat.py b/apps/chat/views/v3/chat.py index 3cee1d170ee..82068a0c3b5 100644 --- a/apps/chat/views/v3/chat.py +++ b/apps/chat/views/v3/chat.py @@ -13,7 +13,7 @@ from django.core.cache import cache from django.http import HttpResponse, StreamingHttpResponse from django.utils.translation import gettext_lazy as _ -from drf_spectacular.utils import extend_schema +from drf_spectacular.utils import OpenApiResponse, extend_schema from drf_spectacular.types import OpenApiTypes from drf_spectacular.utils import OpenApiParameter from rest_framework.parsers import MultiPartParser @@ -46,7 +46,7 @@ from common.constants.cache_version import Cache_Version from common.exception.app_exception import AppApiException from common.log.log import _get_ip_address, log, record_log -from common.result import result +from common.result import DefaultResultSerializer, result from common.utils.rsa_util import decrypt from knowledge.models import FileSourceType from maxkb.const import CONFIG @@ -469,7 +469,13 @@ class ChatUserProfileView(APIView): description=_("Get current user information"), operation_id=_("V3 Get current user information"), # type: ignore tags=[_("V3 Chat User")], # type: ignore - responses=UserProfileAPI.get_response(), + responses={ + 200: UserProfileAPI.get_response(), + 401: OpenApiResponse( + response=DefaultResultSerializer, + description=_("Authentication required"), + ), + }, ) def get(self, request: Request): return result.success(ChatUserProfileSerializer().profile(request.user.profile)) diff --git a/apps/chat/views/v3/chat_user_api_key.py b/apps/chat/views/v3/chat_user_api_key.py index 0c5de342af1..5400429cebc 100644 --- a/apps/chat/views/v3/chat_user_api_key.py +++ b/apps/chat/views/v3/chat_user_api_key.py @@ -3,8 +3,8 @@ from common.auth import ChatTokenAuth from common.log.log import log -from common.result import result -from drf_spectacular.utils import extend_schema +from common.result import DefaultResultSerializer, result +from drf_spectacular.utils import OpenApiResponse, extend_schema from rest_framework.request import Request from rest_framework.views import APIView @@ -20,7 +20,13 @@ class ChatUserApiKeyView(APIView): description=_("Create ChatUserAPIKey"), summary=_("Create ChatUserAPIKey"), operation_id="V3 Create ChatUserAPIKey", - responses=None, + responses={ + 200: None, + 401: OpenApiResponse( + response=DefaultResultSerializer, + description=_("Authentication required"), + ), + }, tags=[_("V3 Chat User API Key")], # type: ignore ) @log(menu="Chat User API Key", operate="Add chat user API key") @@ -32,7 +38,13 @@ def post(self, request: Request): description=_("Get ChatUserAPIKey"), summary=_("Get ChatUserAPIKey"), operation_id="V3 Get ChatUserAPIKey", - responses=None, + responses={ + 200: None, + 401: OpenApiResponse( + response=DefaultResultSerializer, + description=_("Authentication required"), + ), + }, tags=[_("V3 Chat User API Key")], # type: ignore ) @log(menu="Chat User API Key", operate="Get chat user API key") diff --git a/apps/common/result/api.py b/apps/common/result/api.py index 24685a77d04..45241c857f8 100644 --- a/apps/common/result/api.py +++ b/apps/common/result/api.py @@ -1,11 +1,14 @@ # coding=utf-8 """ - @project: MaxKB - @Author:虎虎 - @file: api.py - @date:2025/4/14 15:20 - @desc: +@project: MaxKB +@Author:虎虎 +@file: api.py +@date:2025/4/14 15:20 +@desc: """ + +import copy + from django.utils.translation import gettext_lazy as _ from rest_framework import serializers @@ -14,9 +17,11 @@ class DefaultResultSerializer(serializers.Serializer): """ 响应结果 """ - code = serializers.IntegerField(required=True, help_text=_('response code'), label=_('response code')) - message = serializers.CharField(required=False, default="success", help_text=_('error prompt'), - label=_('error prompt')) + + code = serializers.IntegerField(required=True, help_text=_("response code"), label=_("response code")) + message = serializers.CharField( + required=False, default="success", help_text=_("error prompt"), label=_("error prompt") + ) data = serializers.BooleanField(required=False, default=True) @@ -24,33 +29,45 @@ class ResultSerializer(serializers.Serializer): """ 响应结果 """ - code = serializers.IntegerField(required=True, help_text=_('response code'), label=_('response code')) - message = serializers.CharField(required=False, default="success", help_text=_('error prompt'), - label=_('error prompt')) + + code = serializers.IntegerField(required=True, help_text=_("response code"), label=_("response code")) + message = serializers.CharField( + required=False, default="success", help_text=_("error prompt"), label=_("error prompt") + ) def get_data(self): pass - def __init__(self, **kwargs): - self.fields['data'] = self.get_data() - super().__init__(**kwargs) + def __init__(self, *args, **kwargs): + super().__init__(*args, **kwargs) + self.fields["data"] = self.get_data() class PageDataResponse(serializers.Serializer): """ 分页数据 """ - total = serializers.IntegerField(required=True, label=_('total number of data')) - current = serializers.IntegerField(required=True, label=_('current page')) - size = serializers.IntegerField(required=True, label=_('page size')) - def __init__(self, records, **kwargs): - self.fields['records'] = records - super().__init__(**kwargs) + total = serializers.IntegerField(required=True, label=_("total number of data")) + current = serializers.IntegerField(required=True, label=_("current page")) + size = serializers.IntegerField(required=True, label=_("page size")) + def __init__(self, records=None, *args, **kwargs): + super().__init__(*args, **kwargs) + if records is not None: + self._records_serializer = copy.deepcopy(records) + self.fields["records"] = records -class ResultPageSerializer(ResultSerializer): - def __init__(self, **kwargs): - super().__init__(**kwargs) - self.fields['data'] = PageDataResponse(self.get_data()) +class ResultPageSerializer(ResultSerializer): + def __init__(self, *args, **kwargs): + super().__init__(*args, **kwargs) + records = self.get_data() + if isinstance(records, PageDataResponse): + records = records._records_serializer + page_class = type( + f"{self.__class__.__name__}PageData", + (PageDataResponse,), + {"__module__": PageDataResponse.__module__}, + ) + self.fields["data"] = page_class(records) diff --git a/apps/models_provider/api/model.py b/apps/models_provider/api/model.py index 5d7fb2721c2..5ac87255733 100644 --- a/apps/models_provider/api/model.py +++ b/apps/models_provider/api/model.py @@ -13,6 +13,82 @@ def get_data(self): return ModelModelSerializer() +class ModelDetailSerializer(serializers.Serializer): + id = serializers.UUIDField(required=True, label=_("model id")) + provider = serializers.CharField(required=True, label=_("provider")) + name = serializers.CharField(required=True, label=_("model name")) + model_type = serializers.CharField(required=True, label=_("model type")) + model_name = serializers.CharField(required=True, label=_("base model")) + status = serializers.CharField(required=True, label=_("status")) + meta = serializers.DictField(required=False, allow_null=True, label=_("model meta")) + credential = serializers.DictField(required=False, label=_("certification information")) + workspace_id = serializers.CharField(required=True, label=_("workspace id")) + nick_name = serializers.CharField(required=False, allow_blank=True, label=_("nick name")) + username = serializers.CharField(required=False, allow_blank=True, label=_("username")) + + +class ModelMetaSerializer(serializers.Serializer): + id = serializers.UUIDField(required=True, label=_("model id")) + provider = serializers.CharField(required=True, label=_("provider")) + name = serializers.CharField(required=True, label=_("model name")) + model_type = serializers.CharField(required=True, label=_("model type")) + model_name = serializers.CharField(required=True, label=_("base model")) + status = serializers.CharField(required=True, label=_("status")) + meta = serializers.DictField(required=False, allow_null=True, label=_("model meta")) + workspace_id = serializers.CharField(required=True, label=_("workspace id")) + + +class ModelSummarySerializer(serializers.Serializer): + id = serializers.UUIDField(required=True, label=_("model id")) + provider = serializers.CharField(required=True, label=_("provider")) + name = serializers.CharField(required=True, label=_("model name")) + model_type = serializers.CharField(required=True, label=_("model type")) + model_name = serializers.CharField(required=True, label=_("base model")) + status = serializers.CharField(required=True, label=_("status")) + meta = serializers.DictField(required=False, allow_null=True, label=_("model meta")) + user = serializers.UUIDField(required=False, label=_("user id")) + user_id = serializers.UUIDField(required=False, label=_("user id")) + username = serializers.CharField(required=False, allow_blank=True, label=_("username")) + nick_name = serializers.CharField(required=False, allow_blank=True, label=_("nick name")) + credential = serializers.CharField(required=False, label=_("certification information")) + model_params_form = serializers.JSONField(required=False, label=_("parameter configuration")) + workspace_id = serializers.CharField(required=False, label=_("workspace id")) + workspace_name = serializers.CharField(required=False, allow_blank=True, label=_("workspace name")) + create_time = serializers.DateTimeField(required=False, label=_("create time")) + update_time = serializers.DateTimeField(required=False, label=_("update time")) + resource_count = serializers.IntegerField(required=False, label=_("resource count")) + + +class ModelGroupedListSerializer(serializers.Serializer): + shared_model = ModelSummarySerializer(many=True) + model = ModelSummarySerializer(many=True) + + +class ModelDetailResponse(ResultSerializer): + def get_data(self): + return ModelDetailSerializer() + + +class ModelMetaResponse(ResultSerializer): + def get_data(self): + return ModelMetaSerializer() + + +class ModelGroupedListResponse(APIMixin): + @staticmethod + def get_response(): + class ModelGroupedListResult(ResultSerializer): + def get_data(self): + return ModelGroupedListSerializer() + + return ModelGroupedListResult + + +class ModelSummaryListResponse(ResultSerializer): + def get_data(self): + return ModelSummarySerializer(many=True) + + class ModelListResponse(APIMixin): @staticmethod def get_response(): @@ -118,7 +194,7 @@ def get_request(): @staticmethod def get_response(): - return ModelCreateResponse + return ModelDetailResponse class ModelEditApi(APIMixin): @@ -128,10 +204,10 @@ def get_request(): @staticmethod def get_response(): - return ModelCreateResponse + return ModelDetailResponse class DefaultModelResponse(APIMixin): @staticmethod def get_response(): - return DefaultResultSerializer() + return DefaultResultSerializer diff --git a/apps/models_provider/api/provide.py b/apps/models_provider/api/provide.py index 9e0921dbbd3..d74136d66e5 100644 --- a/apps/models_provider/api/provide.py +++ b/apps/models_provider/api/provide.py @@ -9,7 +9,7 @@ class ProvideResponse(ResultSerializer): def get_data(self): - return ProvideSerializer() + return ProvideSerializer(many=True) class ProvideSerializer(serializers.Serializer): diff --git a/apps/models_provider/serializers/model_serializer.py b/apps/models_provider/serializers/model_serializer.py index 133083f5c99..e4720266a63 100644 --- a/apps/models_provider/serializers/model_serializer.py +++ b/apps/models_provider/serializers/model_serializer.py @@ -282,14 +282,20 @@ def is_valid(self, model=None, raise_exception=False): 500, _("base model【{model_name}】already exists").format(model_name=self.data.get("name")) ) - ModelSerializer.model_to_dict(model) - provider = model.provider + if provider not in ModelProvideConstants: + raise BadRequest400(400, _("provider is invalid")) + provider_handler = ModelProvideConstants[provider] model_type = self.data.get("model_type") or model.model_type + model_type_list = [item.get("value") for item in provider_handler.get_model_type_list()] + if model_type not in model_type_list: + raise BadRequest400(400, _("model_type is invalid")) + + ModelSerializer.model_to_dict(model) + model_name = self.data.get("model_name") or model.model_name credential = self.data.get("credential") - provider_handler = ModelProvideConstants[provider] - model_credential = ModelProvideConstants[provider].get_model_credential(model_type, model_name) + model_credential = provider_handler.get_model_credential(model_type, model_name) source_model_credential = json.loads(rsa_long_decrypt(model.credential)) source_encryption_model_credential = model_credential.encryption_dict(source_model_credential) if credential is None: @@ -318,6 +324,10 @@ def is_valid(self, *, raise_exception=False): provider_handler = ModelProvideConstants[provider] except KeyError as error: raise BadRequest400(400, _("provider is invalid")) from error + model_type = self.data.get("model_type") + model_type_list = [item.get("value") for item in provider_handler.get_model_type_list()] + if model_type not in model_type_list: + raise BadRequest400(400, _("model_type is invalid")) model_params_form = self.data.get("model_params_form") if not isinstance(model_params_form, list): raise BadRequest400(400, _("model_params_form must be a list")) diff --git a/apps/models_provider/views/model.py b/apps/models_provider/views/model.py index 7d13f9499d3..5cfbbadbf08 100644 --- a/apps/models_provider/views/model.py +++ b/apps/models_provider/views/model.py @@ -19,7 +19,16 @@ from django.db.models import QuerySet from django.utils.translation import gettext_lazy as _ from drf_spectacular.utils import extend_schema -from models_provider.api.model import DefaultModelResponse, GetModelApi, ModelCreateAPI, ModelEditApi, ModelListResponse +from models_provider.api.model import ( + DefaultModelResponse, + GetModelApi, + ModelCreateAPI, + ModelEditApi, + ModelGroupedListResponse, + ModelListResponse, + ModelMetaResponse, + ModelSummaryListResponse, +) from models_provider.api.chat_completion import ChatCompletionAPI from models_provider.api.prompt_generate import PromptGenerateAPI from models_provider.api.provide import ProvideApi @@ -283,7 +292,7 @@ class ModelMeta(APIView): description=_("Query model meta information, this interface does not carry authentication information"), operation_id=_("Query model meta information, this interface does not carry authentication information"), # type: ignore parameters=GetModelApi.get_parameters(), - responses=GetModelApi.get_response(), + responses=ModelMetaResponse, tags=[_("Model")], # type: ignore ) @has_permissions( @@ -340,7 +349,7 @@ class WorkspaceSharedModelSetting(APIView): description=_("Get Share model by workspace id"), operation_id=_("Get Share model by workspace id"), # type: ignore parameters=ModelListResponse.get_parameters(), - responses=DefaultModelResponse.get_response(), + responses=ModelSummaryListResponse, tags=[_("Shared Model")], # type: ignore ) @has_permissions( @@ -366,7 +375,7 @@ class ModelList(APIView): description=_("Query all model list"), operation_id=_("Query all model list"), # type: ignore parameters=ModelListResponse.get_parameters(), - responses=ModelListResponse.get_response(), + responses=ModelGroupedListResponse.get_response(), tags=[_("Model")], # type: ignore ) @has_permissions( diff --git a/apps/trigger/api/trigger.py b/apps/trigger/api/trigger.py index c2d59dc16a0..6acdb4ea3f2 100644 --- a/apps/trigger/api/trigger.py +++ b/apps/trigger/api/trigger.py @@ -1,26 +1,27 @@ # coding=utf-8 """ - @project: MaxKB - @Author:niu - @file: trigger.py - @date:2026/1/14 15:49 - @desc: +@project: MaxKB +@Author:niu +@file: trigger.py +@date:2026/1/14 15:49 +@desc: """ + from drf_spectacular.types import OpenApiTypes from drf_spectacular.utils import OpenApiParameter from rest_framework import serializers from django.utils.translation import gettext_lazy as _ from common.mixins.api_mixin import APIMixin -from common.result import ResultSerializer +from common.result import ResultPageSerializer, ResultSerializer from knowledge.serializers.common import BatchSerializer from trigger.serializers.task_source_trigger import TaskSourceTriggerEditRequest from trigger.serializers.trigger import TriggerCreateRequest, TriggerResponse, BatchActiveSerializer class TriggerQueryResponseSerializer(serializers.Serializer): - id = serializers.UUIDField(required=True, help_text="触发器id", label='触发器id') - workspace_id = serializers.CharField(required=True, help_text="触发器工作空间", label='触发器工作空间') - name = serializers.CharField(required=True, help_text="触发器名称", label='触发器名称') + id = serializers.UUIDField(required=True, help_text="触发器id", label="触发器id") + workspace_id = serializers.CharField(required=True, help_text="触发器工作空间", label="触发器工作空间") + name = serializers.CharField(required=True, help_text="触发器名称", label="触发器名称") desc = serializers.CharField(required=True, help_text="触发器描述", label="触发器描述") trigger_type = serializers.CharField(required=True, help_text="触发器类型", label="触发器类型") type = serializers.CharField(required=True, help_text="资源类型", label="资源类型") @@ -31,7 +32,12 @@ class TriggerQueryResponseSerializer(serializers.Serializer): update_time = serializers.CharField(required=True, help_text="修改时间", label="修改时间") -class TriggerTaskRecordResponse(ResultSerializer): +class TriggerListResponse(ResultSerializer): + def get_data(self): + return TriggerQueryResponseSerializer(many=True) + + +class TriggerPageResponse(ResultPageSerializer): def get_data(self): return TriggerQueryResponseSerializer(many=True) @@ -44,7 +50,7 @@ def get_parameters(): name="workspace_id", description="工作空间id", type=OpenApiTypes.STR, - location='path', + location="path", required=True, ), OpenApiParameter( @@ -81,31 +87,33 @@ def get_parameters(): @staticmethod def get_response(): - return TriggerTaskRecordResponse + return TriggerListResponse class TriggerQueryPageAPI(APIMixin): @staticmethod def get_parameters(): - return [TriggerQueryAPI.get_parameters(), - OpenApiParameter( - name="current_page", - description=_("Current page"), - type=OpenApiTypes.INT, - location='path', - required=True, - ), - OpenApiParameter( - name="page_size", - description=_("Page size"), - type=OpenApiTypes.INT, - location='path', - required=True, - )] + return [ + TriggerQueryAPI.get_parameters(), + OpenApiParameter( + name="current_page", + description=_("Current page"), + type=OpenApiTypes.INT, + location="path", + required=True, + ), + OpenApiParameter( + name="page_size", + description=_("Page size"), + type=OpenApiTypes.INT, + location="path", + required=True, + ), + ] @staticmethod def get_response(): - return TriggerQueryAPI.get_response() + return TriggerPageResponse class TriggerCreateAPI(APIMixin): @@ -116,7 +124,7 @@ def get_parameters(): name="workspace_id", description="工作空间id", type=OpenApiTypes.STR, - location='path', + location="path", required=True, ), ] @@ -138,21 +146,21 @@ def get_parameters(): name="workspace_id", description="工作空间id", type=OpenApiTypes.STR, - location='path', + location="path", required=True, ), OpenApiParameter( name="source_id", description="资源id", type=OpenApiTypes.STR, - location='path', + location="path", required=True, ), OpenApiParameter( name="source_type", description="资源类型", type=OpenApiTypes.STR, - location='path', + location="path", required=True, ), ] @@ -174,7 +182,7 @@ def get_parameters(): name="workspace_id", description="工作空间id", type=OpenApiTypes.STR, - location='path', + location="path", required=True, ) ] @@ -198,14 +206,14 @@ def get_parameters(): name="workspace_id", description="工作空间id", type=OpenApiTypes.STR, - location='path', + location="path", required=True, ), OpenApiParameter( name="trigger_id", description="触发器id", type=OpenApiTypes.STR, - location='path', + location="path", required=True, ), ] @@ -237,21 +245,21 @@ def get_parameters(): name="workspace_id", description="工作空间id", type=OpenApiTypes.STR, - location='path', + location="path", required=True, ), OpenApiParameter( name="source_id", description="资源id", type=OpenApiTypes.STR, - location='path', + location="path", required=True, ), OpenApiParameter( name="source_type", description="资源类型", type=OpenApiTypes.STR, - location='path', + location="path", required=True, ), ] @@ -269,28 +277,28 @@ def get_parameters(): name="workspace_id", description="工作空间id", type=OpenApiTypes.STR, - location='path', + location="path", required=True, ), OpenApiParameter( name="source_id", description="资源id", type=OpenApiTypes.STR, - location='path', + location="path", required=True, ), OpenApiParameter( name="source_type", description="资源类型", type=OpenApiTypes.STR, - location='path', + location="path", required=True, ), OpenApiParameter( name="trigger_id", description="触发器id", type=OpenApiTypes.STR, - location='path', + location="path", required=True, ), ] diff --git a/apps/trigger/api/trigger_task.py b/apps/trigger/api/trigger_task.py index 3958d4eed6a..1b581c6ad2c 100644 --- a/apps/trigger/api/trigger_task.py +++ b/apps/trigger/api/trigger_task.py @@ -1,25 +1,26 @@ # coding=utf-8 """ - @project: MaxKB - @Author:虎虎 - @file: trigger_task.py - @date:2026/1/28 16:37 - @desc: +@project: MaxKB +@Author:虎虎 +@file: trigger_task.py +@date:2026/1/28 16:37 +@desc: """ + from drf_spectacular.types import OpenApiTypes from drf_spectacular.utils import OpenApiParameter from django.utils.translation import gettext_lazy as _ from rest_framework import serializers from common.mixins.api_mixin import APIMixin -from common.result import ResultSerializer +from common.result import ResultPageSerializer, ResultSerializer from trigger.serializers.trigger_task import ChatRecordSerializerModel, TriggerTaskResponse class TriggerTaskRecordResultSerializer(serializers.Serializer): - id = serializers.UUIDField(required=True, help_text="任务记录id", label='任务记录id') - state = serializers.CharField(required=True, help_text="任务记录状态", label='任务记录状态') - source_type = serializers.CharField(required=True, help_text="资源类型", label='资源类型') + id = serializers.UUIDField(required=True, help_text="任务记录id", label="任务记录id") + state = serializers.CharField(required=True, help_text="任务记录状态", label="任务记录状态") + source_type = serializers.CharField(required=True, help_text="资源类型", label="资源类型") source_name = serializers.CharField(required=True, help_text="资源名称", label="资源名称") source_id = serializers.CharField(required=True, help_text="资源id", label="资源id") task_record_id = serializers.CharField(required=True, help_text="资源任务记录id", label="资源任务记录id") @@ -29,7 +30,12 @@ class TriggerTaskRecordResultSerializer(serializers.Serializer): update_time = serializers.CharField(required=True, help_text="修改时间", label="修改时间") -class TriggerTaskRecordResponse(ResultSerializer): +class TriggerTaskRecordListResponse(ResultSerializer): + def get_data(self): + return TriggerTaskRecordResultSerializer(many=True) + + +class TriggerTaskRecordPageResponse(ResultPageSerializer): def get_data(self): return TriggerTaskRecordResultSerializer(many=True) @@ -47,8 +53,11 @@ def get_data(self): class TriggerTaskAPI(APIMixin): @staticmethod def get_system_parameters(): - return [parameter for parameter in TriggerTaskRecordExecutionDetailsAPI.get_parameters() if - not parameter.name == 'workspace_id'] + return [ + parameter + for parameter in TriggerTaskRecordExecutionDetailsAPI.get_parameters() + if not parameter.name == "workspace_id" + ] @staticmethod def get_parameters(): @@ -57,14 +66,14 @@ def get_parameters(): name="workspace_id", description="工作空间id", type=OpenApiTypes.STR, - location='path', + location="path", required=True, ), OpenApiParameter( name="trigger_id", description="触发器id", type=OpenApiTypes.STR, - location='path', + location="path", required=True, ), ] @@ -77,8 +86,11 @@ def get_response(): class TriggerTaskRecordPageAPI(APIMixin): @staticmethod def get_system_parameters(): - return [parameter for parameter in TriggerTaskRecordExecutionDetailsAPI.get_parameters() if - not parameter.name == 'workspace_id'] + return [ + parameter + for parameter in TriggerTaskRecordExecutionDetailsAPI.get_parameters() + if not parameter.name == "workspace_id" + ] @staticmethod def get_parameters(): @@ -87,63 +99,66 @@ def get_parameters(): name="workspace_id", description="工作空间id", type=OpenApiTypes.STR, - location='path', + location="path", required=True, ), OpenApiParameter( name="trigger_id", description="触发器id", type=OpenApiTypes.STR, - location='path', + location="path", required=True, ), OpenApiParameter( name="current_page", description=_("Current page"), type=OpenApiTypes.INT, - location='path', + location="path", required=True, ), OpenApiParameter( name="page_size", description=_("Page size"), type=OpenApiTypes.INT, - location='path', + location="path", required=True, ), OpenApiParameter( name="name", description="任务名称", type=OpenApiTypes.STR, - location='query', + location="query", required=True, ), OpenApiParameter( name="state", description="状态", type=OpenApiTypes.STR, - location='query', + location="query", required=True, ), OpenApiParameter( name="order", description="排序字段", type=OpenApiTypes.STR, - location='query', + location="query", required=True, ), ] @staticmethod def get_response(): - return TriggerTaskRecordResponse + return TriggerTaskRecordPageResponse class TriggerTaskRecordExecutionDetailsAPI(APIMixin): @staticmethod def get_system_parameters(): - return [parameter for parameter in TriggerTaskRecordExecutionDetailsAPI.get_parameters() if - not parameter.name == 'workspace_id'] + return [ + parameter + for parameter in TriggerTaskRecordExecutionDetailsAPI.get_parameters() + if not parameter.name == "workspace_id" + ] @staticmethod def get_parameters(): @@ -152,21 +167,21 @@ def get_parameters(): name="workspace_id", description="工作空间id", type=OpenApiTypes.STR, - location='path', + location="path", required=True, ), OpenApiParameter( name="trigger_id", description="触发器id", type=OpenApiTypes.STR, - location='path', + location="path", required=True, ), OpenApiParameter( name="trigger_task_id", description="触发器任务id", type=OpenApiTypes.STR, - location='path', + location="path", required=True, ), ] diff --git a/apps/users/api/user.py b/apps/users/api/user.py index 0474d09c2ce..9dab995f588 100644 --- a/apps/users/api/user.py +++ b/apps/users/api/user.py @@ -1,20 +1,28 @@ # coding=utf-8 """ - @project: MaxKB - @Author:虎虎 - @file: user.py - @date:2025/4/14 19:23 - @desc: +@project: MaxKB +@Author:虎虎 +@file: user.py +@date:2025/4/14 19:23 +@desc: """ + from django.utils.translation import gettext_lazy as _ from drf_spectacular.types import OpenApiTypes from drf_spectacular.utils import OpenApiParameter from rest_framework import serializers from common.mixins.api_mixin import APIMixin -from common.result import ResultSerializer, DefaultResultSerializer -from users.serializers.user import UserProfileResponse, CreateUserSerializer, UserManageSerializer, \ - UserInstanceSerializer, RePasswordSerializer, CheckCodeSerializer, SendEmailSerializer +from common.result import ResultSerializer, DefaultResultSerializer, ResultPageSerializer +from users.serializers.user import ( + UserProfileResponse, + CreateUserSerializer, + UserManageSerializer, + UserInstanceSerializer, + RePasswordSerializer, + CheckCodeSerializer, + SendEmailSerializer, +) class ApiUserProfileResponse(ResultSerializer): @@ -23,20 +31,17 @@ def get_data(self): class RoleSettingRequestSerializer(serializers.Serializer): - role_id = serializers.CharField(required=True, label=_('Role ID')) + role_id = serializers.CharField(required=True, label=_("Role ID")) workspace_ids = serializers.ListField( - child=serializers.CharField(required=False), - required=False, - label=_('Workspace IDs') + child=serializers.CharField(required=False), required=False, label=_("Workspace IDs") ) class CreateUserRequestSerializer(CreateUserSerializer): - role_setting = RoleSettingRequestSerializer(required=False, label=_('Role Setting'), allow_null=True, many=True) + role_setting = RoleSettingRequestSerializer(required=False, label=_("Role Setting"), allow_null=True, many=True) class UserProfileAPI(APIMixin): - @staticmethod def get_response(): return ApiUserProfileResponse @@ -47,13 +52,15 @@ def get_request(): @staticmethod def get_parameters(): - return [OpenApiParameter( - name="user_id", - description=_('User ID'), - type=OpenApiTypes.STR, - location=OpenApiParameter.PATH, - required=True, - )] + return [ + OpenApiParameter( + name="user_id", + description=_("User ID"), + type=OpenApiTypes.STR, + location=OpenApiParameter.PATH, + required=True, + ) + ] class WorkspaceUserAPI(APIMixin): @@ -62,18 +69,18 @@ def get_parameters(): return [ OpenApiParameter( name="workspace_id", - description=_('Workspace ID'), + description=_("Workspace ID"), type=OpenApiTypes.STR, location=OpenApiParameter.PATH, required=True, ), OpenApiParameter( name="nick_name", - description=_('Nick name'), + description=_("Nick name"), type=OpenApiTypes.STR, location=OpenApiParameter.QUERY, required=False, - ) + ), ] @staticmethod @@ -82,8 +89,8 @@ def get_response(): class WorkspaceUser(serializers.Serializer): - id = serializers.CharField(required=True, label=_('id')) - username = serializers.CharField(required=True, label=_('Username')) + id = serializers.CharField(required=True, label=_("id")) + username = serializers.CharField(required=True, label=_("Username")) class WorkspaceUserListResponse(ResultSerializer): @@ -92,14 +99,13 @@ def get_data(self): class UserPasswordResponse(APIMixin): - @staticmethod def get_response(): return PasswordResponse class Password(serializers.Serializer): - password = serializers.CharField(required=True, label=_('Password')) + password = serializers.CharField(required=True, label=_("Password")) class PasswordResponse(ResultSerializer): @@ -108,19 +114,21 @@ def get_data(self): class EditUserRequestSerializer(UserManageSerializer.UserEditInstance): - role_setting = RoleSettingRequestSerializer(required=False, label=_('Role Setting'), allow_null=True, many=True) + role_setting = RoleSettingRequestSerializer(required=False, label=_("Role Setting"), allow_null=True, many=True) class EditUserApi(APIMixin): @staticmethod def get_parameters(): - return [OpenApiParameter( - name="user_id", - description=_('User ID'), - type=OpenApiTypes.STR, - location=OpenApiParameter.PATH, - required=True, - )] + return [ + OpenApiParameter( + name="user_id", + description=_("User ID"), + type=OpenApiTypes.STR, + location=OpenApiParameter.PATH, + required=True, + ) + ] @staticmethod def get_request(): @@ -130,18 +138,21 @@ def get_request(): class DeleteUserApi(APIMixin): @staticmethod def get_parameters(): - return [OpenApiParameter( - name="user_id", - description=_('User ID'), - type=OpenApiTypes.STR, - location=OpenApiParameter.PATH, - required=True, - )] + return [ + OpenApiParameter( + name="user_id", + description=_("User ID"), + type=OpenApiTypes.STR, + location=OpenApiParameter.PATH, + required=True, + ) + ] @staticmethod def get_request(): - return serializers.ListSerializer(child=serializers.CharField(required=True), required=True, - label=_('User IDs')) + return serializers.ListSerializer( + child=serializers.CharField(required=True), required=True, label=_("User IDs") + ) class ChangeUserPasswordApi(APIMixin): @@ -155,20 +166,27 @@ def get_data(self): return UserInstanceSerializer(many=True) +class UserPageResponse(ResultPageSerializer): + def get_data(self): + return UserInstanceSerializer(many=True) + + class UserPageApi(APIMixin): @staticmethod def get_parameters(): - return [OpenApiParameter( - name="email_or_username", - description=_('Email or Username'), - type=OpenApiTypes.STR, - location=OpenApiParameter.QUERY, - required=False, - )] + return [ + OpenApiParameter( + name="email_or_username", + description=_("Email or Username"), + type=OpenApiTypes.STR, + location=OpenApiParameter.QUERY, + required=False, + ) + ] @staticmethod def get_response(): - return UserListResponse + return UserPageResponse class UserListApi(APIMixin): @@ -177,7 +195,7 @@ def get_parameters(): return [ OpenApiParameter( name="nick_name", - description=_('Nick name'), + description=_("Nick name"), type=OpenApiTypes.STR, location=OpenApiParameter.QUERY, required=False, @@ -192,17 +210,19 @@ def get_response(): class TestWorkspacePermissionUserApi(APIMixin): @staticmethod def get_parameters(): - return [OpenApiParameter( - # 参数的名称是done - name="workspace_id", - # 对参数的备注 - description="工作空间id", - # 指定参数的类型 - type=OpenApiTypes.STR, - location=OpenApiParameter.PATH, - # 指定必须给 - required=True, - )] + return [ + OpenApiParameter( + # 参数的名称是done + name="workspace_id", + # 对参数的备注 + description="工作空间id", + # 指定参数的类型 + type=OpenApiTypes.STR, + location=OpenApiParameter.PATH, + # 指定必须给 + required=True, + ) + ] class ResetPasswordAPI(APIMixin): @@ -232,7 +252,7 @@ def get_response(): class LanguageSerializer(serializers.Serializer): - language = serializers.CharField(required=True, label=_('Language')) + language = serializers.CharField(required=True, label=_("Language")) class SwitchUserLanguageAPI(APIMixin):