Skip to content

Commit 8ec4233

Browse files
asukaminato0721autofix-ci[bot]hyoban
authored
fix: doc not gen bug (#31547)
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com> Co-authored-by: Stephen Zhou <[email protected]>
1 parent e482588 commit 8ec4233

27 files changed

+473
-265
lines changed

api/controllers/common/schema.py

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,11 @@
11
"""Helpers for registering Pydantic models with Flask-RESTX namespaces."""
22

3+
from enum import StrEnum
4+
35
from flask_restx import Namespace
4-
from pydantic import BaseModel
6+
from pydantic import BaseModel, TypeAdapter
7+
8+
from controllers.console import console_ns
59

610
DEFAULT_REF_TEMPLATE_SWAGGER_2_0 = "#/definitions/{model}"
711

@@ -19,8 +23,25 @@ def register_schema_models(namespace: Namespace, *models: type[BaseModel]) -> No
1923
register_schema_model(namespace, model)
2024

2125

26+
def get_or_create_model(model_name: str, field_def):
27+
existing = console_ns.models.get(model_name)
28+
if existing is None:
29+
existing = console_ns.model(model_name, field_def)
30+
return existing
31+
32+
33+
def register_enum_models(namespace: Namespace, *models: type[StrEnum]) -> None:
34+
"""Register multiple StrEnum with a namespace."""
35+
for model in models:
36+
namespace.schema_model(
37+
model.__name__, TypeAdapter(model).json_schema(ref_template=DEFAULT_REF_TEMPLATE_SWAGGER_2_0)
38+
)
39+
40+
2241
__all__ = [
2342
"DEFAULT_REF_TEMPLATE_SWAGGER_2_0",
43+
"get_or_create_model",
44+
"register_enum_models",
2445
"register_schema_model",
2546
"register_schema_models",
2647
]

api/controllers/console/apikey.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,10 +22,10 @@
2222
"created_at": TimestampField,
2323
}
2424

25-
api_key_list = {"data": fields.List(fields.Nested(api_key_fields), attribute="items")}
26-
2725
api_key_item_model = console_ns.model("ApiKeyItem", api_key_fields)
2826

27+
api_key_list = {"data": fields.List(fields.Nested(api_key_item_model), attribute="items")}
28+
2929
api_key_list_model = console_ns.model(
3030
"ApiKeyList", {"data": fields.List(fields.Nested(api_key_item_model), attribute="items")}
3131
)

api/controllers/console/app/app.py

Lines changed: 42 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,11 @@
99
from sqlalchemy.orm import Session
1010
from werkzeug.exceptions import BadRequest
1111

12-
from controllers.common.schema import register_schema_models
12+
from controllers.common.helpers import FileInfo
13+
from controllers.common.schema import register_enum_models, register_schema_models
1314
from controllers.console import console_ns
1415
from controllers.console.app.wraps import get_app_model
16+
from controllers.console.workspace.models import LoadBalancingPayload
1517
from controllers.console.wraps import (
1618
account_initialization_required,
1719
cloud_edition_billing_resource_check,
@@ -22,18 +24,36 @@
2224
)
2325
from core.file import helpers as file_helpers
2426
from core.ops.ops_trace_manager import OpsTraceManager
25-
from core.workflow.enums import NodeType
27+
from core.rag.retrieval.retrieval_methods import RetrievalMethod
28+
from core.workflow.enums import NodeType, WorkflowExecutionStatus
2629
from extensions.ext_database import db
2730
from libs.login import current_account_with_tenant, login_required
28-
from models import App, Workflow
31+
from models import App, DatasetPermissionEnum, Workflow
2932
from models.model import IconType
3033
from services.app_dsl_service import AppDslService, ImportMode
3134
from services.app_service import AppService
3235
from services.enterprise.enterprise_service import EnterpriseService
36+
from services.entities.knowledge_entities.knowledge_entities import (
37+
DataSource,
38+
InfoList,
39+
NotionIcon,
40+
NotionInfo,
41+
NotionPage,
42+
PreProcessingRule,
43+
RerankingModel,
44+
Rule,
45+
Segmentation,
46+
WebsiteInfo,
47+
WeightKeywordSetting,
48+
WeightModel,
49+
WeightVectorSetting,
50+
)
3351
from services.feature_service import FeatureService
3452

3553
ALLOW_CREATE_APP_MODES = ["chat", "agent-chat", "advanced-chat", "workflow", "completion"]
3654

55+
register_enum_models(console_ns, IconType)
56+
3757

3858
class AppListQuery(BaseModel):
3959
page: int = Field(default=1, ge=1, le=99999, description="Page number (1-99999)")
@@ -151,7 +171,7 @@ def _build_icon_url(icon_type: str | IconType | None, icon: str | None) -> str |
151171
if icon is None or icon_type is None:
152172
return None
153173
icon_type_value = icon_type.value if isinstance(icon_type, IconType) else str(icon_type)
154-
if icon_type_value.lower() != IconType.IMAGE.value:
174+
if icon_type_value.lower() != IconType.IMAGE:
155175
return None
156176
return file_helpers.get_signed_file_url(icon)
157177

@@ -391,6 +411,8 @@ class AppExportResponse(ResponseModel):
391411
data: str
392412

393413

414+
register_enum_models(console_ns, RetrievalMethod, WorkflowExecutionStatus, DatasetPermissionEnum)
415+
394416
register_schema_models(
395417
console_ns,
396418
AppListQuery,
@@ -414,6 +436,22 @@ class AppExportResponse(ResponseModel):
414436
AppDetailWithSite,
415437
AppPagination,
416438
AppExportResponse,
439+
Segmentation,
440+
PreProcessingRule,
441+
Rule,
442+
WeightVectorSetting,
443+
WeightKeywordSetting,
444+
WeightModel,
445+
RerankingModel,
446+
InfoList,
447+
NotionInfo,
448+
FileInfo,
449+
WebsiteInfo,
450+
NotionPage,
451+
NotionIcon,
452+
RerankingModel,
453+
DataSource,
454+
LoadBalancingPayload,
417455
)
418456

419457

api/controllers/console/app/app_import.py

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -41,14 +41,14 @@
4141

4242
class AppImportPayload(BaseModel):
4343
mode: str = Field(..., description="Import mode")
44-
yaml_content: str | None = None
45-
yaml_url: str | None = None
46-
name: str | None = None
47-
description: str | None = None
48-
icon_type: str | None = None
49-
icon: str | None = None
50-
icon_background: str | None = None
51-
app_id: str | None = None
44+
yaml_content: str | None = Field(None)
45+
yaml_url: str | None = Field(None)
46+
name: str | None = Field(None)
47+
description: str | None = Field(None)
48+
icon_type: str | None = Field(None)
49+
icon: str | None = Field(None)
50+
icon_background: str | None = Field(None)
51+
app_id: str | None = Field(None)
5252

5353

5454
console_ns.schema_model(

api/controllers/console/app/workflow.py

Lines changed: 1 addition & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
import services
1313
from controllers.console import console_ns
1414
from controllers.console.app.error import ConversationCompletedError, DraftWorkflowNotExist, DraftWorkflowNotSync
15+
from controllers.console.app.workflow_run import workflow_run_node_execution_model
1516
from controllers.console.app.wraps import get_app_model
1617
from controllers.console.wraps import account_initialization_required, edit_permission_required, setup_required
1718
from controllers.web.error import InvokeRateLimitError as InvokeRateLimitHttpError
@@ -35,7 +36,6 @@
3536
from factories import file_factory, variable_factory
3637
from fields.member_fields import simple_account_fields
3738
from fields.workflow_fields import workflow_fields, workflow_pagination_fields
38-
from fields.workflow_run_fields import workflow_run_node_execution_fields
3939
from libs import helper
4040
from libs.datetime_utils import naive_utc_now
4141
from libs.helper import TimestampField, uuid_value
@@ -88,26 +88,6 @@
8888
workflow_pagination_fields_copy["items"] = fields.List(fields.Nested(workflow_model), attribute="items")
8989
workflow_pagination_model = console_ns.model("WorkflowPagination", workflow_pagination_fields_copy)
9090

91-
# Reuse workflow_run_node_execution_model from workflow_run.py if already registered
92-
# Otherwise register it here
93-
from fields.end_user_fields import simple_end_user_fields
94-
95-
simple_end_user_model = None
96-
try:
97-
simple_end_user_model = console_ns.models.get("SimpleEndUser")
98-
except AttributeError:
99-
pass
100-
if simple_end_user_model is None:
101-
simple_end_user_model = console_ns.model("SimpleEndUser", simple_end_user_fields)
102-
103-
workflow_run_node_execution_model = None
104-
try:
105-
workflow_run_node_execution_model = console_ns.models.get("WorkflowRunNodeExecution")
106-
except AttributeError:
107-
pass
108-
if workflow_run_node_execution_model is None:
109-
workflow_run_node_execution_model = console_ns.model("WorkflowRunNodeExecution", workflow_run_node_execution_fields)
110-
11191

11292
class SyncDraftWorkflowPayload(BaseModel):
11393
graph: dict[str, Any]

api/controllers/console/app/workflow_trigger.py

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,14 @@
11
import logging
22

33
from flask import request
4-
from flask_restx import Resource, marshal_with
4+
from flask_restx import Resource, fields, marshal_with
55
from pydantic import BaseModel
66
from sqlalchemy import select
77
from sqlalchemy.orm import Session
88
from werkzeug.exceptions import NotFound
99

1010
from configs import dify_config
11+
from controllers.common.schema import get_or_create_model
1112
from extensions.ext_database import db
1213
from fields.workflow_trigger_fields import trigger_fields, triggers_list_fields, webhook_trigger_fields
1314
from libs.login import current_user, login_required
@@ -22,6 +23,14 @@
2223
logger = logging.getLogger(__name__)
2324
DEFAULT_REF_TEMPLATE_SWAGGER_2_0 = "#/definitions/{model}"
2425

26+
trigger_model = get_or_create_model("WorkflowTrigger", trigger_fields)
27+
28+
triggers_list_fields_copy = triggers_list_fields.copy()
29+
triggers_list_fields_copy["data"] = fields.List(fields.Nested(trigger_model))
30+
triggers_list_model = get_or_create_model("WorkflowTriggerList", triggers_list_fields_copy)
31+
32+
webhook_trigger_model = get_or_create_model("WebhookTrigger", webhook_trigger_fields)
33+
2534

2635
class Parser(BaseModel):
2736
node_id: str
@@ -48,7 +57,7 @@ class WebhookTriggerApi(Resource):
4857
@login_required
4958
@account_initialization_required
5059
@get_app_model(mode=AppMode.WORKFLOW)
51-
@marshal_with(webhook_trigger_fields)
60+
@marshal_with(webhook_trigger_model)
5261
def get(self, app_model: App):
5362
"""Get webhook trigger for a node"""
5463
args = Parser.model_validate(request.args.to_dict(flat=True)) # type: ignore
@@ -80,7 +89,7 @@ class AppTriggersApi(Resource):
8089
@login_required
8190
@account_initialization_required
8291
@get_app_model(mode=AppMode.WORKFLOW)
83-
@marshal_with(triggers_list_fields)
92+
@marshal_with(triggers_list_model)
8493
def get(self, app_model: App):
8594
"""Get app triggers list"""
8695
assert isinstance(current_user, Account)
@@ -120,7 +129,7 @@ class AppTriggerEnableApi(Resource):
120129
@account_initialization_required
121130
@edit_permission_required
122131
@get_app_model(mode=AppMode.WORKFLOW)
123-
@marshal_with(trigger_fields)
132+
@marshal_with(trigger_model)
124133
def post(self, app_model: App):
125134
"""Update app trigger (enable/disable)"""
126135
args = ParserEnable.model_validate(console_ns.payload)

api/controllers/console/datasets/data_source.py

Lines changed: 55 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,21 +3,28 @@
33
from typing import Any, cast
44

55
from flask import request
6-
from flask_restx import Resource, marshal_with
6+
from flask_restx import Resource, fields, marshal_with
77
from pydantic import BaseModel, Field
88
from sqlalchemy import select
99
from sqlalchemy.orm import Session
1010
from werkzeug.exceptions import NotFound
1111

12-
from controllers.common.schema import register_schema_model
12+
from controllers.common.schema import get_or_create_model, register_schema_model
1313
from core.datasource.entities.datasource_entities import DatasourceProviderType, OnlineDocumentPagesMessage
1414
from core.datasource.online_document.online_document_plugin import OnlineDocumentDatasourcePlugin
1515
from core.indexing_runner import IndexingRunner
1616
from core.rag.extractor.entity.datasource_type import DatasourceType
1717
from core.rag.extractor.entity.extract_setting import ExtractSetting, NotionInfo
1818
from core.rag.extractor.notion_extractor import NotionExtractor
1919
from extensions.ext_database import db
20-
from fields.data_source_fields import integrate_list_fields, integrate_notion_info_list_fields
20+
from fields.data_source_fields import (
21+
integrate_fields,
22+
integrate_icon_fields,
23+
integrate_list_fields,
24+
integrate_notion_info_list_fields,
25+
integrate_page_fields,
26+
integrate_workspace_fields,
27+
)
2128
from libs.datetime_utils import naive_utc_now
2229
from libs.login import current_account_with_tenant, login_required
2330
from models import DataSourceOauthBinding, Document
@@ -49,6 +56,49 @@ class DataSourceNotionPreviewQuery(BaseModel):
4956
register_schema_model(console_ns, NotionEstimatePayload)
5057

5158

59+
integrate_icon_model = get_or_create_model("DataSourceIntegrateIcon", integrate_icon_fields)
60+
61+
integrate_page_fields_copy = integrate_page_fields.copy()
62+
integrate_page_fields_copy["page_icon"] = fields.Nested(integrate_icon_model, allow_null=True)
63+
integrate_page_model = get_or_create_model("DataSourceIntegratePage", integrate_page_fields_copy)
64+
65+
integrate_workspace_fields_copy = integrate_workspace_fields.copy()
66+
integrate_workspace_fields_copy["pages"] = fields.List(fields.Nested(integrate_page_model))
67+
integrate_workspace_model = get_or_create_model("DataSourceIntegrateWorkspace", integrate_workspace_fields_copy)
68+
69+
integrate_fields_copy = integrate_fields.copy()
70+
integrate_fields_copy["source_info"] = fields.Nested(integrate_workspace_model)
71+
integrate_model = get_or_create_model("DataSourceIntegrate", integrate_fields_copy)
72+
73+
integrate_list_fields_copy = integrate_list_fields.copy()
74+
integrate_list_fields_copy["data"] = fields.List(fields.Nested(integrate_model))
75+
integrate_list_model = get_or_create_model("DataSourceIntegrateList", integrate_list_fields_copy)
76+
77+
notion_page_fields = {
78+
"page_name": fields.String,
79+
"page_id": fields.String,
80+
"page_icon": fields.Nested(integrate_icon_model, allow_null=True),
81+
"is_bound": fields.Boolean,
82+
"parent_id": fields.String,
83+
"type": fields.String,
84+
}
85+
notion_page_model = get_or_create_model("NotionIntegratePage", notion_page_fields)
86+
87+
notion_workspace_fields = {
88+
"workspace_name": fields.String,
89+
"workspace_id": fields.String,
90+
"workspace_icon": fields.String,
91+
"pages": fields.List(fields.Nested(notion_page_model)),
92+
}
93+
notion_workspace_model = get_or_create_model("NotionIntegrateWorkspace", notion_workspace_fields)
94+
95+
integrate_notion_info_list_fields_copy = integrate_notion_info_list_fields.copy()
96+
integrate_notion_info_list_fields_copy["notion_info"] = fields.List(fields.Nested(notion_workspace_model))
97+
integrate_notion_info_list_model = get_or_create_model(
98+
"NotionIntegrateInfoList", integrate_notion_info_list_fields_copy
99+
)
100+
101+
52102
@console_ns.route(
53103
"/data-source/integrates",
54104
"/data-source/integrates/<uuid:binding_id>/<string:action>",
@@ -57,7 +107,7 @@ class DataSourceApi(Resource):
57107
@setup_required
58108
@login_required
59109
@account_initialization_required
60-
@marshal_with(integrate_list_fields)
110+
@marshal_with(integrate_list_model)
61111
def get(self):
62112
_, current_tenant_id = current_account_with_tenant()
63113

@@ -142,7 +192,7 @@ class DataSourceNotionListApi(Resource):
142192
@setup_required
143193
@login_required
144194
@account_initialization_required
145-
@marshal_with(integrate_notion_info_list_fields)
195+
@marshal_with(integrate_notion_info_list_model)
146196
def get(self):
147197
current_user, current_tenant_id = current_account_with_tenant()
148198

0 commit comments

Comments
 (0)