mirror of
https://github.com/langgenius/dify.git
synced 2026-07-21 02:28:30 +08:00
refactor(api): remove member field compatibility (#37966)
Co-authored-by: WH-2099 <wh2099@pm.me> Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com> Co-authored-by: Asuka Minato <i@asukaminato.eu.org>
This commit is contained in:
parent
77ae583b44
commit
904fadde20
@ -13,7 +13,6 @@ import services
|
||||
from controllers.common.fields import (
|
||||
AudioBinaryResponse,
|
||||
AudioTranscriptResponse,
|
||||
GeneratedAppResponse,
|
||||
SimpleResultResponse,
|
||||
)
|
||||
from controllers.common.fields import Parameters as ParametersResponse
|
||||
@ -391,7 +390,6 @@ register_response_schema_models(
|
||||
ParametersResponse,
|
||||
AudioBinaryResponse,
|
||||
AudioTranscriptResponse,
|
||||
GeneratedAppResponse,
|
||||
SimpleResultResponse,
|
||||
SiteResponse,
|
||||
SuggestedQuestionsResponse,
|
||||
@ -406,7 +404,7 @@ simple_account_model = console_ns.models[TrialSimpleAccount.__name__]
|
||||
class TrialAppWorkflowRunApi(TrialAppResource):
|
||||
@trial_feature_enable
|
||||
@console_ns.expect(console_ns.models[WorkflowRunRequest.__name__])
|
||||
@console_ns.response(200, "Success", console_ns.models[GeneratedAppResponse.__name__])
|
||||
@console_ns.response(200, "Success")
|
||||
@with_current_user
|
||||
@with_session
|
||||
def post(self, session: Session, current_user: Account, trial_app):
|
||||
@ -434,6 +432,7 @@ class TrialAppWorkflowRunApi(TrialAppResource):
|
||||
streaming=True,
|
||||
)
|
||||
RecommendedAppService.add_trial_app_record(db.session, app_id, user_id)
|
||||
# response-contract:ignore compact_generate_response
|
||||
return helper.compact_generate_response(response)
|
||||
except ProviderTokenNotInitError as ex:
|
||||
raise ProviderNotInitializeError(ex.description)
|
||||
@ -478,7 +477,7 @@ class TrialAppWorkflowTaskStopApi(TrialAppResource):
|
||||
|
||||
class TrialChatApi(TrialAppResource):
|
||||
@console_ns.expect(console_ns.models[ChatRequest.__name__])
|
||||
@console_ns.response(200, "Success", console_ns.models[GeneratedAppResponse.__name__])
|
||||
@console_ns.response(200, "Success")
|
||||
@trial_feature_enable
|
||||
@with_current_user
|
||||
@with_session
|
||||
@ -513,6 +512,7 @@ class TrialChatApi(TrialAppResource):
|
||||
streaming=True,
|
||||
)
|
||||
RecommendedAppService.add_trial_app_record(db.session, app_id, user_id)
|
||||
# response-contract:ignore compact_generate_response
|
||||
return helper.compact_generate_response(response)
|
||||
except services.errors.conversation.ConversationNotExistsError:
|
||||
raise NotFound("Conversation Not Exists.")
|
||||
@ -680,7 +680,7 @@ class TrialChatTextApi(TrialAppResource):
|
||||
|
||||
class TrialCompletionApi(TrialAppResource):
|
||||
@console_ns.expect(console_ns.models[CompletionRequest.__name__])
|
||||
@console_ns.response(200, "Success", console_ns.models[GeneratedAppResponse.__name__])
|
||||
@console_ns.response(200, "Success")
|
||||
@trial_feature_enable
|
||||
@with_current_user
|
||||
@with_session
|
||||
@ -710,6 +710,7 @@ class TrialCompletionApi(TrialAppResource):
|
||||
)
|
||||
|
||||
RecommendedAppService.add_trial_app_record(db.session, app_id, user_id)
|
||||
# response-contract:ignore compact_generate_response
|
||||
return helper.compact_generate_response(response)
|
||||
except services.errors.conversation.ConversationNotExistsError:
|
||||
raise NotFound("Conversation Not Exists.")
|
||||
|
||||
@ -4,7 +4,7 @@ from typing import Any
|
||||
from urllib.parse import quote
|
||||
|
||||
from flask import Response, request
|
||||
from flask_restx import Resource, marshal
|
||||
from flask_restx import Resource
|
||||
from pydantic import Field as PydanticField
|
||||
from pydantic import field_validator
|
||||
from sqlalchemy.orm import Session, sessionmaker
|
||||
@ -37,8 +37,7 @@ from controllers.console.wraps import (
|
||||
from core.plugin.entities.plugin import PluginDependency
|
||||
from extensions.ext_database import db
|
||||
from fields.base import ResponseModel
|
||||
from fields.snippet_fields import snippet_fields, snippet_list_fields
|
||||
from libs.helper import to_timestamp
|
||||
from libs.helper import dump_response, to_timestamp
|
||||
from libs.login import login_required
|
||||
from models import Account
|
||||
from models.snippet import SnippetType
|
||||
@ -198,13 +197,16 @@ class CustomizedSnippetsApi(Resource):
|
||||
tag_ids=query.tag_ids,
|
||||
)
|
||||
|
||||
return {
|
||||
"data": marshal(snippets, snippet_list_fields),
|
||||
"page": query.page,
|
||||
"limit": query.limit,
|
||||
"total": total,
|
||||
"has_more": has_more,
|
||||
}, 200
|
||||
return dump_response(
|
||||
SnippetPaginationResponse,
|
||||
{
|
||||
"data": snippets,
|
||||
"page": query.page,
|
||||
"limit": query.limit,
|
||||
"total": total,
|
||||
"has_more": has_more,
|
||||
},
|
||||
), 200
|
||||
|
||||
@console_ns.doc("create_customized_snippet")
|
||||
@console_ns.expect(console_ns.models.get(CreateSnippetPayload.__name__))
|
||||
@ -245,7 +247,7 @@ class CustomizedSnippetsApi(Resource):
|
||||
except ValueError as e:
|
||||
return {"message": str(e)}, 400
|
||||
|
||||
return marshal(snippet, snippet_fields), 201
|
||||
return dump_response(SnippetResponse, snippet), 201
|
||||
|
||||
|
||||
@console_ns.route("/workspaces/current/customized-snippets/<uuid:snippet_id>")
|
||||
@ -268,7 +270,7 @@ class CustomizedSnippetDetailApi(Resource):
|
||||
if not snippet:
|
||||
raise NotFound("Snippet not found")
|
||||
|
||||
return marshal(snippet, snippet_fields), 200
|
||||
return dump_response(SnippetResponse, snippet), 200
|
||||
|
||||
@console_ns.doc("update_customized_snippet")
|
||||
@console_ns.expect(console_ns.models.get(UpdateSnippetPayload.__name__))
|
||||
@ -317,7 +319,7 @@ class CustomizedSnippetDetailApi(Resource):
|
||||
except ValueError as e:
|
||||
return {"message": str(e)}, 400
|
||||
|
||||
return marshal(snippet, snippet_fields), 200
|
||||
return dump_response(SnippetResponse, snippet), 200
|
||||
|
||||
@console_ns.doc("delete_customized_snippet")
|
||||
@console_ns.response(204, "Snippet deleted successfully")
|
||||
@ -533,4 +535,4 @@ class CustomizedSnippetUseCountIncrementApi(Resource):
|
||||
session.commit()
|
||||
session.refresh(snippet)
|
||||
|
||||
return {"result": "success", "use_count": snippet.use_count}, 200
|
||||
return SnippetUseCountResponse(result="success", use_count=snippet.use_count).model_dump(mode="json"), 200
|
||||
|
||||
@ -32,6 +32,7 @@ class EndpointEntity(BasePluginEntity):
|
||||
entity of an endpoint
|
||||
"""
|
||||
|
||||
# TODO: Confirm daemon masks secret-input settings before endpoint list responses expose them.
|
||||
settings: dict[str, Any]
|
||||
tenant_id: str
|
||||
plugin_id: str
|
||||
|
||||
@ -1,271 +0,0 @@
|
||||
import json
|
||||
from typing import override
|
||||
|
||||
from flask_restx import fields
|
||||
|
||||
from fields.workflow_fields import workflow_partial_fields
|
||||
from libs.helper import AppIconUrlField, TimestampField
|
||||
|
||||
|
||||
class JsonStringField(fields.Raw):
|
||||
@override
|
||||
def format(self, value):
|
||||
if isinstance(value, str):
|
||||
try:
|
||||
return json.loads(value)
|
||||
except (json.JSONDecodeError, TypeError):
|
||||
return value
|
||||
return value
|
||||
|
||||
|
||||
class OpaqueRawField(fields.Raw):
|
||||
@override
|
||||
def schema(self) -> dict[str, object]:
|
||||
return {"type": "object"}
|
||||
|
||||
|
||||
class StringListRawField(fields.Raw):
|
||||
@override
|
||||
def schema(self) -> dict[str, object]:
|
||||
return {"type": "array", "items": {"type": "string"}}
|
||||
|
||||
|
||||
class ObjectListRawField(fields.Raw):
|
||||
@override
|
||||
def schema(self) -> dict[str, object]:
|
||||
return {"type": "array", "items": {"type": "object"}}
|
||||
|
||||
|
||||
app_detail_kernel_fields = {
|
||||
"id": fields.String,
|
||||
"name": fields.String,
|
||||
"description": fields.String,
|
||||
"mode": fields.String(attribute="mode_compatible_with_agent"),
|
||||
"icon_type": fields.String,
|
||||
"icon": fields.String,
|
||||
"icon_background": fields.String,
|
||||
"icon_url": AppIconUrlField,
|
||||
}
|
||||
|
||||
related_app_list = {
|
||||
"data": fields.List(fields.Nested(app_detail_kernel_fields)),
|
||||
"total": fields.Integer,
|
||||
}
|
||||
|
||||
model_config_fields = {
|
||||
"opening_statement": fields.String,
|
||||
"suggested_questions": StringListRawField(attribute="suggested_questions_list"),
|
||||
"suggested_questions_after_answer": OpaqueRawField(attribute="suggested_questions_after_answer_dict"),
|
||||
"speech_to_text": OpaqueRawField(attribute="speech_to_text_dict"),
|
||||
"text_to_speech": OpaqueRawField(attribute="text_to_speech_dict"),
|
||||
"retriever_resource": OpaqueRawField(attribute="retriever_resource_dict"),
|
||||
"annotation_reply": OpaqueRawField(attribute="annotation_reply_dict"),
|
||||
"more_like_this": OpaqueRawField(attribute="more_like_this_dict"),
|
||||
"sensitive_word_avoidance": OpaqueRawField(attribute="sensitive_word_avoidance_dict"),
|
||||
"external_data_tools": ObjectListRawField(attribute="external_data_tools_list"),
|
||||
"model": OpaqueRawField(attribute="model_dict"),
|
||||
"user_input_form": ObjectListRawField(attribute="user_input_form_list"),
|
||||
"dataset_query_variable": fields.String,
|
||||
"pre_prompt": fields.String,
|
||||
"agent_mode": OpaqueRawField(attribute="agent_mode_dict"),
|
||||
"prompt_type": fields.String,
|
||||
"chat_prompt_config": OpaqueRawField(attribute="chat_prompt_config_dict"),
|
||||
"completion_prompt_config": OpaqueRawField(attribute="completion_prompt_config_dict"),
|
||||
"dataset_configs": OpaqueRawField(attribute="dataset_configs_dict"),
|
||||
"file_upload": OpaqueRawField(attribute="file_upload_dict"),
|
||||
"created_by": fields.String,
|
||||
"created_at": TimestampField,
|
||||
"updated_by": fields.String,
|
||||
"updated_at": TimestampField,
|
||||
}
|
||||
|
||||
tag_fields = {"id": fields.String, "name": fields.String, "type": fields.String}
|
||||
|
||||
app_detail_fields = {
|
||||
"id": fields.String,
|
||||
"name": fields.String,
|
||||
"description": fields.String,
|
||||
"mode": fields.String(attribute="mode_compatible_with_agent"),
|
||||
"icon": fields.String,
|
||||
"icon_background": fields.String,
|
||||
"enable_site": fields.Boolean,
|
||||
"enable_api": fields.Boolean,
|
||||
"model_config": fields.Nested(model_config_fields, attribute="app_model_config", allow_null=True),
|
||||
"workflow": fields.Nested(workflow_partial_fields, allow_null=True),
|
||||
"tracing": OpaqueRawField,
|
||||
"use_icon_as_answer_icon": fields.Boolean,
|
||||
"created_by": fields.String,
|
||||
"created_at": TimestampField,
|
||||
"updated_by": fields.String,
|
||||
"updated_at": TimestampField,
|
||||
"access_mode": fields.String,
|
||||
"tags": fields.List(fields.Nested(tag_fields)),
|
||||
"permission_keys": fields.List(fields.String()),
|
||||
}
|
||||
|
||||
prompt_config_fields = {
|
||||
"prompt_template": fields.String,
|
||||
}
|
||||
|
||||
model_config_partial_fields = {
|
||||
"model": OpaqueRawField(attribute="model_dict"),
|
||||
"pre_prompt": fields.String,
|
||||
"created_by": fields.String,
|
||||
"created_at": TimestampField,
|
||||
"updated_by": fields.String,
|
||||
"updated_at": TimestampField,
|
||||
}
|
||||
|
||||
app_partial_fields = {
|
||||
"id": fields.String,
|
||||
"name": fields.String,
|
||||
"max_active_requests": OpaqueRawField(),
|
||||
"description": fields.String(attribute="desc_or_prompt"),
|
||||
"mode": fields.String(attribute="mode_compatible_with_agent"),
|
||||
"icon_type": fields.String,
|
||||
"icon": fields.String,
|
||||
"icon_background": fields.String,
|
||||
"icon_url": AppIconUrlField,
|
||||
"model_config": fields.Nested(model_config_partial_fields, attribute="app_model_config", allow_null=True),
|
||||
"workflow": fields.Nested(workflow_partial_fields, allow_null=True),
|
||||
"use_icon_as_answer_icon": fields.Boolean,
|
||||
"created_by": fields.String,
|
||||
"created_at": TimestampField,
|
||||
"updated_by": fields.String,
|
||||
"updated_at": TimestampField,
|
||||
"tags": fields.List(fields.Nested(tag_fields)),
|
||||
"access_mode": fields.String,
|
||||
"create_user_name": fields.String,
|
||||
"author_name": fields.String,
|
||||
"has_draft_trigger": fields.Boolean,
|
||||
"permission_keys": fields.List(fields.String()),
|
||||
}
|
||||
|
||||
|
||||
app_pagination_fields = {
|
||||
"page": fields.Integer,
|
||||
"limit": fields.Integer(attribute="per_page"),
|
||||
"total": fields.Integer,
|
||||
"has_more": fields.Boolean(attribute="has_next"),
|
||||
"data": fields.List(fields.Nested(app_partial_fields), attribute="items"),
|
||||
}
|
||||
|
||||
template_fields = {
|
||||
"name": fields.String,
|
||||
"icon": fields.String,
|
||||
"icon_background": fields.String,
|
||||
"description": fields.String,
|
||||
"mode": fields.String,
|
||||
"model_config": fields.Nested(model_config_fields),
|
||||
}
|
||||
|
||||
template_list_fields = {
|
||||
"data": fields.List(fields.Nested(template_fields)),
|
||||
}
|
||||
|
||||
site_fields = {
|
||||
"access_token": fields.String(attribute="code"),
|
||||
"code": fields.String,
|
||||
"title": fields.String,
|
||||
"icon_type": fields.String,
|
||||
"icon": fields.String,
|
||||
"icon_background": fields.String,
|
||||
"icon_url": AppIconUrlField,
|
||||
"description": fields.String,
|
||||
"default_language": fields.String,
|
||||
"chat_color_theme": fields.String,
|
||||
"chat_color_theme_inverted": fields.Boolean,
|
||||
"customize_domain": fields.String,
|
||||
"copyright": fields.String,
|
||||
"privacy_policy": fields.String,
|
||||
"custom_disclaimer": fields.String,
|
||||
"customize_token_strategy": fields.String,
|
||||
"prompt_public": fields.Boolean,
|
||||
"app_base_url": fields.String,
|
||||
"show_workflow_steps": fields.Boolean,
|
||||
"use_icon_as_answer_icon": fields.Boolean,
|
||||
"created_by": fields.String,
|
||||
"created_at": TimestampField,
|
||||
"updated_by": fields.String,
|
||||
"updated_at": TimestampField,
|
||||
}
|
||||
|
||||
deleted_tool_fields = {
|
||||
"type": fields.String,
|
||||
"tool_name": fields.String,
|
||||
"provider_id": fields.String,
|
||||
}
|
||||
|
||||
app_detail_fields_with_site = {
|
||||
"id": fields.String,
|
||||
"name": fields.String,
|
||||
"description": fields.String,
|
||||
"mode": fields.String(attribute="mode_compatible_with_agent"),
|
||||
"icon_type": fields.String,
|
||||
"icon": fields.String,
|
||||
"icon_background": fields.String,
|
||||
"icon_url": AppIconUrlField,
|
||||
"enable_site": fields.Boolean,
|
||||
"enable_api": fields.Boolean,
|
||||
"model_config": fields.Nested(model_config_fields, attribute="app_model_config", allow_null=True),
|
||||
"workflow": fields.Nested(workflow_partial_fields, allow_null=True),
|
||||
"api_base_url": fields.String,
|
||||
"use_icon_as_answer_icon": fields.Boolean,
|
||||
"max_active_requests": fields.Integer,
|
||||
"created_by": fields.String,
|
||||
"created_at": TimestampField,
|
||||
"updated_by": fields.String,
|
||||
"updated_at": TimestampField,
|
||||
"deleted_tools": fields.List(fields.Nested(deleted_tool_fields)),
|
||||
"access_mode": fields.String,
|
||||
"tags": fields.List(fields.Nested(tag_fields)),
|
||||
"permission_keys": fields.List(fields.String()),
|
||||
"site": fields.Nested(site_fields),
|
||||
}
|
||||
|
||||
|
||||
app_site_fields = {
|
||||
"app_id": fields.String,
|
||||
"access_token": fields.String(attribute="code"),
|
||||
"code": fields.String,
|
||||
"title": fields.String,
|
||||
"icon": fields.String,
|
||||
"icon_background": fields.String,
|
||||
"description": fields.String,
|
||||
"default_language": fields.String,
|
||||
"customize_domain": fields.String,
|
||||
"copyright": fields.String,
|
||||
"privacy_policy": fields.String,
|
||||
"custom_disclaimer": fields.String,
|
||||
"customize_token_strategy": fields.String,
|
||||
"prompt_public": fields.Boolean,
|
||||
"show_workflow_steps": fields.Boolean,
|
||||
"use_icon_as_answer_icon": fields.Boolean,
|
||||
}
|
||||
|
||||
leaked_dependency_fields = {"type": fields.String, "value": OpaqueRawField, "current_identifier": fields.String}
|
||||
|
||||
app_import_fields = {
|
||||
"id": fields.String,
|
||||
"status": fields.String,
|
||||
"app_id": fields.String,
|
||||
"app_mode": fields.String,
|
||||
"current_dsl_version": fields.String,
|
||||
"imported_dsl_version": fields.String,
|
||||
"error": fields.String,
|
||||
}
|
||||
|
||||
app_import_check_dependencies_fields = {
|
||||
"leaked_dependencies": fields.List(fields.Nested(leaked_dependency_fields)),
|
||||
}
|
||||
|
||||
app_server_fields = {
|
||||
"id": fields.String,
|
||||
"name": fields.String,
|
||||
"server_code": fields.String,
|
||||
"description": fields.String,
|
||||
"status": fields.String,
|
||||
"parameters": JsonStringField,
|
||||
"created_at": TimestampField,
|
||||
"updated_at": TimestampField,
|
||||
}
|
||||
@ -2,18 +2,11 @@ from __future__ import annotations
|
||||
|
||||
from datetime import datetime
|
||||
|
||||
from flask_restx import fields
|
||||
from pydantic import Field, computed_field, field_validator
|
||||
|
||||
from fields.base import ResponseModel
|
||||
from libs.helper import build_avatar_url, to_timestamp
|
||||
|
||||
simple_account_fields = {
|
||||
"id": fields.String,
|
||||
"name": fields.String,
|
||||
"email": fields.String,
|
||||
}
|
||||
|
||||
|
||||
class SimpleAccountResponse(ResponseModel):
|
||||
id: str
|
||||
|
||||
@ -1,61 +1,74 @@
|
||||
from typing import override
|
||||
from datetime import datetime
|
||||
from typing import Any
|
||||
|
||||
from flask_restx import fields
|
||||
from pydantic import Field, field_validator
|
||||
|
||||
from fields.member_fields import simple_account_fields
|
||||
from libs.helper import TimestampField
|
||||
from fields.base import ResponseModel
|
||||
from fields.member_fields import SimpleAccountResponse
|
||||
from libs.helper import to_timestamp
|
||||
from models.snippet import SnippetType
|
||||
|
||||
|
||||
class OpaqueRawField(fields.Raw):
|
||||
@override
|
||||
def schema(self) -> dict[str, object]:
|
||||
return {"type": "object"}
|
||||
class SnippetTagResponse(ResponseModel):
|
||||
id: str
|
||||
name: str
|
||||
type: str
|
||||
|
||||
|
||||
tag_fields = {"id": fields.String, "name": fields.String, "type": fields.String}
|
||||
class SnippetListItemResponse(ResponseModel):
|
||||
id: str
|
||||
name: str
|
||||
description: str | None
|
||||
type: SnippetType
|
||||
version: int
|
||||
use_count: int
|
||||
is_published: bool
|
||||
icon_info: dict[str, Any] | None
|
||||
tags: list[SnippetTagResponse]
|
||||
created_by: str | None
|
||||
author_name: str | None
|
||||
created_at: int
|
||||
updated_by: str | None
|
||||
updated_at: int
|
||||
|
||||
# Snippet list item fields (lightweight for list display)
|
||||
snippet_list_fields = {
|
||||
"id": fields.String,
|
||||
"name": fields.String,
|
||||
"description": fields.String,
|
||||
"type": fields.String,
|
||||
"version": fields.Integer,
|
||||
"use_count": fields.Integer,
|
||||
"is_published": fields.Boolean,
|
||||
"icon_info": OpaqueRawField,
|
||||
"tags": fields.List(fields.Nested(tag_fields)),
|
||||
"created_by": fields.String,
|
||||
"author_name": fields.String,
|
||||
"created_at": TimestampField,
|
||||
"updated_by": fields.String,
|
||||
"updated_at": TimestampField,
|
||||
}
|
||||
@field_validator("created_at", "updated_at", mode="before")
|
||||
@classmethod
|
||||
def _normalize_timestamp(cls, value: datetime | int | None) -> int:
|
||||
timestamp = to_timestamp(value)
|
||||
if timestamp is None:
|
||||
raise ValueError("timestamp is required")
|
||||
return timestamp
|
||||
|
||||
# Full snippet fields (includes creator info and graph data)
|
||||
snippet_fields = {
|
||||
"id": fields.String,
|
||||
"name": fields.String,
|
||||
"description": fields.String,
|
||||
"type": fields.String,
|
||||
"version": fields.Integer,
|
||||
"use_count": fields.Integer,
|
||||
"is_published": fields.Boolean,
|
||||
"icon_info": OpaqueRawField,
|
||||
"graph": OpaqueRawField(attribute="graph_dict"),
|
||||
"input_fields": OpaqueRawField(attribute="input_fields_list"),
|
||||
"tags": fields.List(fields.Nested(tag_fields)),
|
||||
"created_by": fields.Nested(simple_account_fields, attribute="created_by_account", allow_null=True),
|
||||
"created_at": TimestampField,
|
||||
"updated_by": fields.Nested(simple_account_fields, attribute="updated_by_account", allow_null=True),
|
||||
"updated_at": TimestampField,
|
||||
}
|
||||
|
||||
# Pagination response fields
|
||||
snippet_pagination_fields = {
|
||||
"data": fields.List(fields.Nested(snippet_list_fields)),
|
||||
"page": fields.Integer,
|
||||
"limit": fields.Integer,
|
||||
"total": fields.Integer,
|
||||
"has_more": fields.Boolean,
|
||||
}
|
||||
class SnippetResponse(ResponseModel):
|
||||
id: str
|
||||
name: str
|
||||
description: str | None
|
||||
type: SnippetType
|
||||
version: int
|
||||
use_count: int
|
||||
is_published: bool
|
||||
icon_info: dict[str, Any] | None
|
||||
graph: dict[str, Any] = Field(validation_alias="graph_dict")
|
||||
input_fields: list[dict[str, Any]] = Field(validation_alias="input_fields_list")
|
||||
tags: list[SnippetTagResponse]
|
||||
created_by: SimpleAccountResponse | None = Field(validation_alias="created_by_account")
|
||||
created_at: int
|
||||
updated_by: SimpleAccountResponse | None = Field(validation_alias="updated_by_account")
|
||||
updated_at: int
|
||||
|
||||
@field_validator("created_at", "updated_at", mode="before")
|
||||
@classmethod
|
||||
def _normalize_timestamp(cls, value: datetime | int | None) -> int:
|
||||
timestamp = to_timestamp(value)
|
||||
if timestamp is None:
|
||||
raise ValueError("timestamp is required")
|
||||
return timestamp
|
||||
|
||||
|
||||
class SnippetPaginationResponse(ResponseModel):
|
||||
data: list[SnippetListItemResponse]
|
||||
page: int
|
||||
limit: int
|
||||
total: int
|
||||
has_more: bool
|
||||
|
||||
@ -1,129 +0,0 @@
|
||||
from typing import override
|
||||
|
||||
from flask_restx import fields
|
||||
|
||||
from core.helper import encrypter
|
||||
from fields.member_fields import simple_account_fields
|
||||
from graphon.variables import SecretVariable, SegmentType, VariableBase
|
||||
from libs.helper import TimestampField
|
||||
|
||||
from ._value_type_serializer import serialize_value_type
|
||||
|
||||
ENVIRONMENT_VARIABLE_SUPPORTED_TYPES = (SegmentType.STRING, SegmentType.NUMBER, SegmentType.SECRET)
|
||||
|
||||
|
||||
class OpaqueRawField(fields.Raw):
|
||||
@override
|
||||
def schema(self) -> dict[str, object]:
|
||||
return {"type": "object"}
|
||||
|
||||
|
||||
class JsonValueRawField(fields.Raw):
|
||||
@override
|
||||
def schema(self) -> dict[str, object]:
|
||||
return {
|
||||
"anyOf": [
|
||||
{"type": "string"},
|
||||
{"type": "integer"},
|
||||
{"type": "number"},
|
||||
{"type": "boolean"},
|
||||
{"type": "object", "additionalProperties": True},
|
||||
{"type": "array", "items": {}},
|
||||
{"type": "null"},
|
||||
]
|
||||
}
|
||||
|
||||
|
||||
class EnvironmentVariableField(fields.Raw):
|
||||
@override
|
||||
def schema(self) -> dict[str, object]:
|
||||
return {"type": "object"}
|
||||
|
||||
@override
|
||||
def format(self, value):
|
||||
# Mask secret variables values in environment_variables
|
||||
if isinstance(value, SecretVariable):
|
||||
return {
|
||||
"id": value.id,
|
||||
"name": value.name,
|
||||
"value": encrypter.full_mask_token(),
|
||||
"value_type": value.value_type.value,
|
||||
"description": value.description,
|
||||
}
|
||||
if isinstance(value, VariableBase):
|
||||
return {
|
||||
"id": value.id,
|
||||
"name": value.name,
|
||||
"value": value.value,
|
||||
"value_type": str(value.value_type.exposed_type()),
|
||||
"description": value.description,
|
||||
}
|
||||
if isinstance(value, dict):
|
||||
value_type_str = value.get("value_type")
|
||||
if not isinstance(value_type_str, str):
|
||||
raise TypeError(
|
||||
f"unexpected type for value_type field, value={value_type_str}, type={type(value_type_str)}"
|
||||
)
|
||||
value_type = SegmentType(value_type_str).exposed_type()
|
||||
if value_type not in ENVIRONMENT_VARIABLE_SUPPORTED_TYPES:
|
||||
raise ValueError(f"Unsupported environment variable value type: {value_type}")
|
||||
return value
|
||||
|
||||
|
||||
conversation_variable_fields = {
|
||||
"id": fields.String,
|
||||
"name": fields.String,
|
||||
"value_type": fields.String(attribute=serialize_value_type),
|
||||
"value": JsonValueRawField,
|
||||
"description": fields.String,
|
||||
}
|
||||
|
||||
pipeline_variable_fields = {
|
||||
"label": fields.String,
|
||||
"variable": fields.String,
|
||||
"type": fields.String,
|
||||
"belong_to_node_id": fields.String,
|
||||
"max_length": fields.Integer,
|
||||
"required": fields.Boolean,
|
||||
"unit": fields.String,
|
||||
"default_value": JsonValueRawField,
|
||||
"options": fields.List(fields.String),
|
||||
"placeholder": fields.String,
|
||||
"tooltips": fields.String,
|
||||
"allowed_file_types": fields.List(fields.String),
|
||||
"allow_file_extension": fields.List(fields.String),
|
||||
"allow_file_upload_methods": fields.List(fields.String),
|
||||
}
|
||||
|
||||
workflow_fields = {
|
||||
"id": fields.String,
|
||||
"graph": OpaqueRawField(attribute="graph_dict"),
|
||||
"features": OpaqueRawField(attribute="features_dict"),
|
||||
"hash": fields.String(attribute="unique_hash"),
|
||||
"version": fields.String,
|
||||
"marked_name": fields.String,
|
||||
"marked_comment": fields.String,
|
||||
"created_by": fields.Nested(simple_account_fields, attribute="created_by_account"),
|
||||
"created_at": TimestampField,
|
||||
"updated_by": fields.Nested(simple_account_fields, attribute="updated_by_account", allow_null=True),
|
||||
"updated_at": TimestampField,
|
||||
"tool_published": fields.Boolean,
|
||||
"environment_variables": fields.List(EnvironmentVariableField()),
|
||||
"conversation_variables": fields.List(fields.Nested(conversation_variable_fields)),
|
||||
"rag_pipeline_variables": fields.List(fields.Nested(pipeline_variable_fields)),
|
||||
}
|
||||
|
||||
workflow_partial_fields = {
|
||||
"id": fields.String,
|
||||
"created_by": fields.String,
|
||||
"created_at": TimestampField,
|
||||
"updated_by": fields.String,
|
||||
"updated_at": TimestampField,
|
||||
}
|
||||
|
||||
workflow_pagination_fields = {
|
||||
"items": fields.List(fields.Nested(workflow_fields), attribute="items"),
|
||||
"page": fields.Integer,
|
||||
"limit": fields.Integer(attribute="limit"),
|
||||
"has_more": fields.Boolean(attribute="has_more"),
|
||||
}
|
||||
@ -9432,9 +9432,9 @@ Bedrock retrieval test (internal use only)
|
||||
|
||||
#### Responses
|
||||
|
||||
| Code | Description | Schema |
|
||||
| ---- | ----------- | ------ |
|
||||
| 200 | Success | **application/json**: [GeneratedAppResponse](#generatedappresponse)<br> |
|
||||
| Code | Description |
|
||||
| ---- | ----------- |
|
||||
| 200 | Success |
|
||||
|
||||
### [POST] /trial-apps/{app_id}/completion-messages
|
||||
#### Parameters
|
||||
@ -9451,9 +9451,9 @@ Bedrock retrieval test (internal use only)
|
||||
|
||||
#### Responses
|
||||
|
||||
| Code | Description | Schema |
|
||||
| ---- | ----------- | ------ |
|
||||
| 200 | Success | **application/json**: [GeneratedAppResponse](#generatedappresponse)<br> |
|
||||
| Code | Description |
|
||||
| ---- | ----------- |
|
||||
| 200 | Success |
|
||||
|
||||
### [GET] /trial-apps/{app_id}/datasets
|
||||
#### Parameters
|
||||
@ -9568,9 +9568,9 @@ Returns the site configuration for the application including theme, icons, and t
|
||||
|
||||
#### Responses
|
||||
|
||||
| Code | Description | Schema |
|
||||
| ---- | ----------- | ------ |
|
||||
| 200 | Success | **application/json**: [GeneratedAppResponse](#generatedappresponse)<br> |
|
||||
| Code | Description |
|
||||
| ---- | ----------- |
|
||||
| 200 | Success |
|
||||
|
||||
### [POST] /trial-apps/{app_id}/workflows/tasks/{task_id}/stop
|
||||
**Stop workflow task**
|
||||
|
||||
@ -1,9 +1,8 @@
|
||||
from datetime import UTC, datetime
|
||||
from types import SimpleNamespace
|
||||
|
||||
from flask_restx import marshal
|
||||
|
||||
from fields.snippet_fields import snippet_list_fields
|
||||
from fields.snippet_fields import SnippetListItemResponse
|
||||
from libs.helper import dump_response
|
||||
|
||||
|
||||
def test_snippet_list_fields_include_author_name() -> None:
|
||||
@ -24,6 +23,6 @@ def test_snippet_list_fields_include_author_name() -> None:
|
||||
updated_at=datetime.fromtimestamp(1704067201, tz=UTC),
|
||||
)
|
||||
|
||||
result = marshal(snippet, snippet_list_fields)
|
||||
result = dump_response(SnippetListItemResponse, snippet)
|
||||
|
||||
assert result["author_name"] == "Alice"
|
||||
|
||||
@ -46,8 +46,6 @@ export type ChatRequest = {
|
||||
retriever_from?: string
|
||||
}
|
||||
|
||||
export type GeneratedAppResponse = JsonValue
|
||||
|
||||
export type CompletionRequest = {
|
||||
files?: Array<unknown> | null
|
||||
inputs: {
|
||||
@ -220,17 +218,6 @@ export type TrialWorkflowPartialResponse = {
|
||||
updated_by?: string | null
|
||||
}
|
||||
|
||||
export type JsonValue
|
||||
= | string
|
||||
| number
|
||||
| number
|
||||
| boolean
|
||||
| {
|
||||
[key: string]: unknown
|
||||
}
|
||||
| Array<unknown>
|
||||
| null
|
||||
|
||||
export type TrialDatasetResponse = {
|
||||
created_at?: number | null
|
||||
created_by?: string | null
|
||||
@ -278,8 +265,6 @@ export type TrialAppModel = {
|
||||
provider: string
|
||||
}
|
||||
|
||||
export type GeneratedAppResponseWritable = JsonValue
|
||||
|
||||
export type SiteWritable = {
|
||||
chat_color_theme?: string | null
|
||||
chat_color_theme_inverted: boolean
|
||||
@ -339,7 +324,9 @@ export type PostTrialAppsByAppIdChatMessagesData = {
|
||||
}
|
||||
|
||||
export type PostTrialAppsByAppIdChatMessagesResponses = {
|
||||
200: GeneratedAppResponse
|
||||
200: {
|
||||
[key: string]: unknown
|
||||
}
|
||||
}
|
||||
|
||||
export type PostTrialAppsByAppIdChatMessagesResponse
|
||||
@ -355,7 +342,9 @@ export type PostTrialAppsByAppIdCompletionMessagesData = {
|
||||
}
|
||||
|
||||
export type PostTrialAppsByAppIdCompletionMessagesResponses = {
|
||||
200: GeneratedAppResponse
|
||||
200: {
|
||||
[key: string]: unknown
|
||||
}
|
||||
}
|
||||
|
||||
export type PostTrialAppsByAppIdCompletionMessagesResponse
|
||||
@ -472,7 +461,9 @@ export type PostTrialAppsByAppIdWorkflowsRunData = {
|
||||
}
|
||||
|
||||
export type PostTrialAppsByAppIdWorkflowsRunResponses = {
|
||||
200: GeneratedAppResponse
|
||||
200: {
|
||||
[key: string]: unknown
|
||||
}
|
||||
}
|
||||
|
||||
export type PostTrialAppsByAppIdWorkflowsRunResponse
|
||||
|
||||
@ -160,22 +160,6 @@ export const zTrialWorkflowPartialResponse = z.object({
|
||||
updated_by: z.string().nullish(),
|
||||
})
|
||||
|
||||
export const zJsonValue = z
|
||||
.union([
|
||||
z.string(),
|
||||
z.int(),
|
||||
z.number(),
|
||||
z.boolean(),
|
||||
z.record(z.string(), z.unknown()),
|
||||
z.array(z.unknown()),
|
||||
])
|
||||
.nullable()
|
||||
|
||||
/**
|
||||
* GeneratedAppResponse
|
||||
*/
|
||||
export const zGeneratedAppResponse = zJsonValue
|
||||
|
||||
/**
|
||||
* TrialDatasetResponse
|
||||
*/
|
||||
@ -344,11 +328,6 @@ export const zTrialAppDetailResponse = z.object({
|
||||
workflow: zTrialWorkflowPartialResponse.nullish(),
|
||||
})
|
||||
|
||||
/**
|
||||
* GeneratedAppResponse
|
||||
*/
|
||||
export const zGeneratedAppResponseWritable = zJsonValue
|
||||
|
||||
/**
|
||||
* Site
|
||||
*/
|
||||
@ -396,7 +375,7 @@ export const zPostTrialAppsByAppIdChatMessagesPath = z.object({
|
||||
/**
|
||||
* Success
|
||||
*/
|
||||
export const zPostTrialAppsByAppIdChatMessagesResponse = zGeneratedAppResponse
|
||||
export const zPostTrialAppsByAppIdChatMessagesResponse = z.record(z.string(), z.unknown())
|
||||
|
||||
export const zPostTrialAppsByAppIdCompletionMessagesBody = zCompletionRequest
|
||||
|
||||
@ -407,7 +386,7 @@ export const zPostTrialAppsByAppIdCompletionMessagesPath = z.object({
|
||||
/**
|
||||
* Success
|
||||
*/
|
||||
export const zPostTrialAppsByAppIdCompletionMessagesResponse = zGeneratedAppResponse
|
||||
export const zPostTrialAppsByAppIdCompletionMessagesResponse = z.record(z.string(), z.unknown())
|
||||
|
||||
export const zGetTrialAppsByAppIdDatasetsPath = z.object({
|
||||
app_id: z.uuid(),
|
||||
@ -482,7 +461,7 @@ export const zPostTrialAppsByAppIdWorkflowsRunPath = z.object({
|
||||
/**
|
||||
* Success
|
||||
*/
|
||||
export const zPostTrialAppsByAppIdWorkflowsRunResponse = zGeneratedAppResponse
|
||||
export const zPostTrialAppsByAppIdWorkflowsRunResponse = z.record(z.string(), z.unknown())
|
||||
|
||||
export const zPostTrialAppsByAppIdWorkflowsTasksByTaskIdStopPath = z.object({
|
||||
app_id: z.uuid(),
|
||||
|
||||
Loading…
Reference in New Issue
Block a user