api.model to BaseModel #20217

Open
opened 2026-02-21 20:06:20 -05:00 by yindo · 5 comments
Owner

Originally created by @asukaminato0721 on GitHub (Nov 9, 2025).

Self Checks

  • I have read the Contributing Guide and Language Policy.
  • This is only for bug report, if you would like to ask a question, please head to Discussions.
  • I have searched for existing issues search for existing issues, including closed ones.
  • I confirm that I am using English to submit this report, otherwise it will be closed.
  • 【中文用户 & Non English User】请使用英语提交,否则会被关闭 :)
  • Please do not modify this template :) and fill in all the required fields.

Dify version

master

Cloud or Self Hosted

Self Hosted (Docker), Self Hosted (Source)

Steps to reproduce

    @api.expect(
        api.model(
            "AppIconRequest",
            {
                "icon": fields.String(required=True, description="Icon data"),
                "icon_type": fields.String(description="Icon type"),
                "icon_background": fields.String(description="Icon background color"),
            },
        )
    )

vs

        parser = (
            reqparse.RequestParser()
            .add_argument("icon", type=str, location="json")
            .add_argument("icon_background", type=str, location="json")
        )

✔️ Expected Behavior

field is the same

Actual Behavior

no the same

Originally created by @asukaminato0721 on GitHub (Nov 9, 2025). ### Self Checks - [x] I have read the [Contributing Guide](https://github.com/langgenius/dify/blob/main/CONTRIBUTING.md) and [Language Policy](https://github.com/langgenius/dify/issues/1542). - [x] This is only for bug report, if you would like to ask a question, please head to [Discussions](https://github.com/langgenius/dify/discussions/categories/general). - [x] I have searched for existing issues [search for existing issues](https://github.com/langgenius/dify/issues), including closed ones. - [x] I confirm that I am using English to submit this report, otherwise it will be closed. - [x] 【中文用户 & Non English User】请使用英语提交,否则会被关闭 :) - [x] Please do not modify this template :) and fill in all the required fields. ### Dify version master ### Cloud or Self Hosted Self Hosted (Docker), Self Hosted (Source) ### Steps to reproduce ``` @api.expect( api.model( "AppIconRequest", { "icon": fields.String(required=True, description="Icon data"), "icon_type": fields.String(description="Icon type"), "icon_background": fields.String(description="Icon background color"), }, ) ) ``` vs ``` parser = ( reqparse.RequestParser() .add_argument("icon", type=str, location="json") .add_argument("icon_background", type=str, location="json") ) ``` ### ✔️ Expected Behavior field is the same ### ❌ Actual Behavior no the same
yindo added the 🐞 buggood first issue🙏 help wanted labels 2026-02-21 20:06:20 -05:00
Author
Owner

@dosubot[bot] commented on GitHub (Nov 9, 2025):

The difference in behavior between api.model (with @api.expect) and reqparse.RequestParser() comes from how Flask-RESTX handles validation and parsing: api.model is designed for schema validation and automatic documentation, while reqparse is for argument parsing from specific locations. This can lead to mismatches in required fields, types, and validation logic if both are used interchangeably.

Dify is actively moving away from reqparse.RequestParser() in favor of defining request schemas with api.model and accessing validated data via api.payload. This approach results in cleaner, shorter code and leverages Flask-RESTX's built-in validation and documentation features. The maintainers have provided proof-of-concept examples and are refactoring the codebase to standardize on this method, eliminating the need for reqparse entirely. You can see this shift and rationale in recent issues and merged pull requests (example, example PR).

If you want consistent field handling, define your request schema with api.model, use @api.expect(..., validate=True), and access the validated payload with api.payload. This will ensure alignment between your API documentation, validation, and runtime behavior, and is now the recommended pattern in Dify.

To reply, just mention @dosu.


How did I do? Good | Irrelevant | Incorrect | Verbose | Hallucination | Report 🐛 | Other  Chat with Dosu Join Discord Share on X

@dosubot[bot] commented on GitHub (Nov 9, 2025): <!-- Answer --> The difference in behavior between `api.model` (with `@api.expect`) and `reqparse.RequestParser()` comes from how Flask-RESTX handles validation and parsing: `api.model` is designed for schema validation and automatic documentation, while `reqparse` is for argument parsing from specific locations. This can lead to mismatches in required fields, types, and validation logic if both are used interchangeably. Dify is actively moving away from `reqparse.RequestParser()` in favor of defining request schemas with `api.model` and accessing validated data via `api.payload`. This approach results in cleaner, shorter code and leverages Flask-RESTX's built-in validation and documentation features. The maintainers have provided proof-of-concept examples and are refactoring the codebase to standardize on this method, eliminating the need for `reqparse` entirely. You can see this shift and rationale in recent issues and merged pull requests ([example](https://github.com/langgenius/dify/issues/27513), [example PR](https://github.com/langgenius/dify/pull/27514)). If you want consistent field handling, define your request schema with `api.model`, use `@api.expect(..., validate=True)`, and access the validated payload with `api.payload`. This will ensure alignment between your API documentation, validation, and runtime behavior, and is now the recommended pattern in Dify. <!-- Dosu Comment Footer --> *To reply, just mention [@dosu](https://go.dosu.dev/dosubot).* --- <sup>How did I do? [Good](https://app.dosu.dev/response-feedback/b6d74f51-806e-4e69-bb8a-12ae69875613?feedback_type=great_response) | [Irrelevant](https://app.dosu.dev/response-feedback/b6d74f51-806e-4e69-bb8a-12ae69875613?feedback_type=irrelevant_answer) | [Incorrect](https://app.dosu.dev/response-feedback/b6d74f51-806e-4e69-bb8a-12ae69875613?feedback_type=incorrect_sources) | [Verbose](https://app.dosu.dev/response-feedback/b6d74f51-806e-4e69-bb8a-12ae69875613?feedback_type=too_verbose) | [Hallucination](https://app.dosu.dev/response-feedback/b6d74f51-806e-4e69-bb8a-12ae69875613?feedback_type=hallucination) | [Report 🐛](https://app.dosu.dev/response-feedback/b6d74f51-806e-4e69-bb8a-12ae69875613?feedback_type=bug_report) | [Other](https://app.dosu.dev/response-feedback/b6d74f51-806e-4e69-bb8a-12ae69875613?feedback_type=other)</sup>&nbsp;&nbsp;[![Chat with Dosu](https://dosu.dev/dosu-chat-badge.svg)](https://app.dosu.dev/6088a4f4-073a-43f3-b3d4-4f06fb0c05a0/ask?utm_source=github)&nbsp;[![Join Discord](https://img.shields.io/badge/join-5865F2?logo=discord&logoColor=white&label=)](https://go.dosu.dev/discord-bot)&nbsp;[![Share on X](https://img.shields.io/badge/X-share-black)](https://twitter.com/intent/tweet?text=%40dosu_ai%20helped%20me%20solve%20this%20issue!&url=https%3A//github.com/langgenius/dify/issues/28015)
Author
Owner

@asukaminato0721 commented on GitHub (Dec 8, 2025):

I'll just use BaseModel for all, so they will align.

@asukaminato0721 commented on GitHub (Dec 8, 2025): I'll just use BaseModel for all, so they will align.
Author
Owner

@dosubot[bot] commented on GitHub (Jan 8, 2026):

Hi, @asukaminato0721. I'm Dosu, and I'm helping the Dify team manage their backlog and am marking this issue as stale.

Issue Summary:

  • You reported inconsistent behavior between api.model and reqparse.RequestParser() in Dify.
  • The maintainer clarified that api.model is for schema validation and documentation, while reqparse is for argument parsing, explaining the differences.
  • Dify is transitioning away from reqparse in favor of api.model with @api.expect and accessing validated data via api.payload.
  • You plan to use BaseModel throughout to ensure consistent behavior aligned with this transition.
  • The issue was resolved with this clarification and planned migration.

Next Steps:

  • Please confirm if this issue is still relevant with the latest version of Dify by commenting here.
  • Otherwise, I will automatically close this issue in 15 days.

Thank you for your understanding and contribution!

@dosubot[bot] commented on GitHub (Jan 8, 2026): Hi, @asukaminato0721. I'm [Dosu](https://dosu.dev), and I'm helping the Dify team manage their backlog and am marking this issue as stale. **Issue Summary:** - You reported inconsistent behavior between `api.model` and `reqparse.RequestParser()` in Dify. - The maintainer clarified that `api.model` is for schema validation and documentation, while `reqparse` is for argument parsing, explaining the differences. - Dify is transitioning away from `reqparse` in favor of `api.model` with `@api.expect` and accessing validated data via `api.payload`. - You plan to use `BaseModel` throughout to ensure consistent behavior aligned with this transition. - The issue was resolved with this clarification and planned migration. **Next Steps:** - Please confirm if this issue is still relevant with the latest version of Dify by commenting here. - Otherwise, I will automatically close this issue in 15 days. Thank you for your understanding and contribution!
Author
Owner

@asukaminato0721 commented on GitHub (Feb 1, 2026):

todo:

rg "\.model\(" | wl-copy
controllers/common/schema.py:        existing = console_ns.model(model_name, field_def)
controllers/console/extension.py:api_based_extension_model = console_ns.model("ApiBasedExtensionModel", api_based_extension_fields)
controllers/console/extension.py:        console_ns.model(
controllers/service_api/app/annotation.py:    return api_or_ns.model("AnnotationList", copied_annotation_list_fields)
controllers/console/apikey.py:api_key_item_model = console_ns.model("ApiKeyItem", api_key_fields)
controllers/console/apikey.py:api_key_list_model = console_ns.model(
controllers/service_api/app/workflow.py:    return api_or_ns.model("WorkflowRun", workflow_run_fields)
controllers/console/workspace/account.py:integrate_model = console_ns.model("AccountIntegrate", integrate_fields)
controllers/console/workspace/account.py:integrate_list_model = console_ns.model(
controllers/console/datasets/datasets_document.py:        console_ns.model(
controllers/console/datasets/hit_testing.py:        existing = console_ns.model(model_name, field_def)
controllers/console/billing/billing.py:        console_ns.model(
fields/workflow_run_fields.py:    return api_or_ns.model("WorkflowRunForLog", workflow_run_for_log_fields)
fields/workflow_run_fields.py:    return api_or_ns.model("WorkflowRunForArchivedLog", workflow_run_for_archived_log_fields)
fields/conversation_variable_fields.py:    return api_or_ns.model("ConversationVariable", conversation_variable_fields)
fields/conversation_variable_fields.py:    return api_or_ns.model("ConversationVariableInfiniteScrollPagination", copied_fields)
fields/annotation_fields.py:    return api_or_ns.model("Annotation", annotation_fields)
fields/workflow_app_log_fields.py:    return api_or_ns.model("WorkflowAppLogPartial", copied_fields)
fields/workflow_app_log_fields.py:    return api_or_ns.model("WorkflowArchivedLogPartial", copied_fields)
fields/workflow_app_log_fields.py:    return api_or_ns.model("WorkflowAppLogPagination", copied_fields)
fields/workflow_app_log_fields.py:    return api_or_ns.model("WorkflowArchivedLogPagination", copied_fields)
fields/tag_fields.py:    return api_or_ns.model("DataSetTag", dataset_tag_fields)
fields/end_user_fields.py:    return api_or_ns.model("SimpleEndUser", simple_end_user_fields)
fields/member_fields.py:    return api_or_ns.model("SimpleAccount", simple_account_fields)
controllers/console/auth/activate.py:        console_ns.model(
controllers/console/auth/activate.py:        console_ns.model(
controllers/console/app/message.py:simple_account_model = console_ns.model(
controllers/console/app/message.py:message_file_model = console_ns.model(
controllers/console/app/message.py:agent_thought_model = console_ns.model(
controllers/console/app/message.py:feedback_model = console_ns.model(
controllers/console/app/message.py:annotation_model = console_ns.model(
controllers/console/app/message.py:annotation_hit_history_model = console_ns.model(
controllers/console/app/message.py:message_detail_model = console_ns.model(
controllers/console/app/message.py:message_infinite_scroll_pagination_model = console_ns.model(
controllers/console/app/conversation.py:simple_account_model = console_ns.model(
controllers/console/app/conversation.py:feedback_stat_model = console_ns.model(
controllers/console/app/conversation.py:status_count_model = console_ns.model(
controllers/console/app/conversation.py:message_file_model = console_ns.model(
controllers/console/app/conversation.py:agent_thought_model = console_ns.model(
controllers/console/app/conversation.py:simple_model_config_model = console_ns.model(
controllers/console/app/conversation.py:model_config_model = console_ns.model(
controllers/console/app/conversation.py:feedback_model = console_ns.model(
controllers/console/app/conversation.py:annotation_model = console_ns.model(
controllers/console/app/conversation.py:annotation_hit_history_model = console_ns.model(
controllers/console/app/conversation.py:simple_message_detail_model = console_ns.model(
controllers/console/app/conversation.py:message_detail_model = console_ns.model(
controllers/console/app/conversation.py:conversation_fields_model = console_ns.model(
controllers/console/app/conversation.py:conversation_pagination_model = console_ns.model(
controllers/console/app/conversation.py:conversation_message_detail_model = console_ns.model(
controllers/console/app/conversation.py:conversation_with_summary_model = console_ns.model(
controllers/console/app/conversation.py:conversation_with_summary_pagination_model = console_ns.model(
controllers/console/app/conversation.py:conversation_detail_model = console_ns.model(
controllers/console/app/site.py:app_site_model = console_ns.model("AppSite", app_site_fields)
controllers/console/app/mcp_server.py:app_server_model = console_ns.model("AppServer", app_server_fields)
controllers/console/app/app_import.py:leaked_dependency_model = console_ns.model("LeakedDependency", leaked_dependency_fields)
controllers/console/app/app_import.py:app_import_model = console_ns.model("AppImport", app_import_fields)
controllers/console/app/app_import.py:app_import_check_dependencies_model = console_ns.model(
controllers/console/app/model_config.py:        console_ns.model(
controllers/console/app/conversation_variables.py:conversation_variable_model = console_ns.model("ConversationVariable", conversation_variable_fields)
controllers/console/app/conversation_variables.py:paginated_conversation_variable_model = console_ns.model(
controllers/console/app/annotation.py:        console_ns.model("AnnotationList", {"data": fields.List(fields.Nested(build_annotation_model(console_ns)))}),
controllers/console/app/annotation.py:        console_ns.model(
controllers/console/app/annotation.py:                    fields.Nested(console_ns.model("AnnotationHitHistoryItem", annotation_hit_history_fields))
controllers/console/app/workflow_run.py:simple_account_model = console_ns.model("SimpleAccount", simple_account_fields)
controllers/console/app/workflow_run.py:simple_end_user_model = console_ns.model("SimpleEndUser", simple_end_user_fields)
controllers/console/app/workflow_run.py:workflow_run_for_list_model = console_ns.model("WorkflowRunForList", workflow_run_for_list_fields_copy)
controllers/console/app/workflow_run.py:advanced_chat_workflow_run_for_list_model = console_ns.model(
controllers/console/app/workflow_run.py:workflow_run_detail_model = console_ns.model("WorkflowRunDetail", workflow_run_detail_fields_copy)
controllers/console/app/workflow_run.py:workflow_run_node_execution_model = console_ns.model(
controllers/console/app/workflow_run.py:workflow_run_count_model = console_ns.model("WorkflowRunCount", workflow_run_count_fields)
controllers/console/app/workflow_run.py:advanced_chat_workflow_run_pagination_model = console_ns.model(
controllers/console/app/workflow_run.py:workflow_run_pagination_model = console_ns.model("WorkflowRunPagination", workflow_run_pagination_fields_copy)
controllers/console/app/workflow_run.py:workflow_run_node_execution_list_model = console_ns.model(
controllers/console/app/workflow_run.py:workflow_run_export_fields = console_ns.model(
controllers/console/app/workflow_draft_variable.py:workflow_draft_variable_without_value_model = console_ns.model(
controllers/console/app/workflow_draft_variable.py:workflow_draft_variable_model = console_ns.model("WorkflowDraftVariable", _WORKFLOW_DRAFT_VARIABLE_FIELDS)
controllers/console/app/workflow_draft_variable.py:workflow_draft_env_variable_model = console_ns.model("WorkflowDraftEnvVariable", _WORKFLOW_DRAFT_ENV_VARIABLE_FIELDS)
controllers/console/app/workflow_draft_variable.py:workflow_draft_env_variable_list_model = console_ns.model(
controllers/console/app/workflow_draft_variable.py:workflow_draft_variable_list_without_value_model = console_ns.model(
controllers/console/app/workflow_draft_variable.py:workflow_draft_variable_list_model = console_ns.model(
controllers/console/app/workflow.py:simple_account_model = console_ns.model("SimpleAccount", simple_account_fields)
controllers/console/app/workflow.py:conversation_variable_model = console_ns.model(
controllers/console/app/workflow.py:pipeline_variable_model = console_ns.model("PipelineVariable", pipeline_variable_fields)
controllers/console/app/workflow.py:workflow_model = console_ns.model("Workflow", workflow_fields_copy)
controllers/console/app/workflow.py:workflow_pagination_model = console_ns.model("WorkflowPagination", workflow_pagination_fields_copy)
controllers/console/app/workflow.py:        console_ns.model(
controllers/console/app/workflow.py:        console_ns.model(
@asukaminato0721 commented on GitHub (Feb 1, 2026): todo: ``` rg "\.model\(" | wl-copy ``` ``` controllers/common/schema.py: existing = console_ns.model(model_name, field_def) controllers/console/extension.py:api_based_extension_model = console_ns.model("ApiBasedExtensionModel", api_based_extension_fields) controllers/console/extension.py: console_ns.model( controllers/service_api/app/annotation.py: return api_or_ns.model("AnnotationList", copied_annotation_list_fields) controllers/console/apikey.py:api_key_item_model = console_ns.model("ApiKeyItem", api_key_fields) controllers/console/apikey.py:api_key_list_model = console_ns.model( controllers/service_api/app/workflow.py: return api_or_ns.model("WorkflowRun", workflow_run_fields) controllers/console/workspace/account.py:integrate_model = console_ns.model("AccountIntegrate", integrate_fields) controllers/console/workspace/account.py:integrate_list_model = console_ns.model( controllers/console/datasets/datasets_document.py: console_ns.model( controllers/console/datasets/hit_testing.py: existing = console_ns.model(model_name, field_def) controllers/console/billing/billing.py: console_ns.model( fields/workflow_run_fields.py: return api_or_ns.model("WorkflowRunForLog", workflow_run_for_log_fields) fields/workflow_run_fields.py: return api_or_ns.model("WorkflowRunForArchivedLog", workflow_run_for_archived_log_fields) fields/conversation_variable_fields.py: return api_or_ns.model("ConversationVariable", conversation_variable_fields) fields/conversation_variable_fields.py: return api_or_ns.model("ConversationVariableInfiniteScrollPagination", copied_fields) fields/annotation_fields.py: return api_or_ns.model("Annotation", annotation_fields) fields/workflow_app_log_fields.py: return api_or_ns.model("WorkflowAppLogPartial", copied_fields) fields/workflow_app_log_fields.py: return api_or_ns.model("WorkflowArchivedLogPartial", copied_fields) fields/workflow_app_log_fields.py: return api_or_ns.model("WorkflowAppLogPagination", copied_fields) fields/workflow_app_log_fields.py: return api_or_ns.model("WorkflowArchivedLogPagination", copied_fields) fields/tag_fields.py: return api_or_ns.model("DataSetTag", dataset_tag_fields) fields/end_user_fields.py: return api_or_ns.model("SimpleEndUser", simple_end_user_fields) fields/member_fields.py: return api_or_ns.model("SimpleAccount", simple_account_fields) controllers/console/auth/activate.py: console_ns.model( controllers/console/auth/activate.py: console_ns.model( controllers/console/app/message.py:simple_account_model = console_ns.model( controllers/console/app/message.py:message_file_model = console_ns.model( controllers/console/app/message.py:agent_thought_model = console_ns.model( controllers/console/app/message.py:feedback_model = console_ns.model( controllers/console/app/message.py:annotation_model = console_ns.model( controllers/console/app/message.py:annotation_hit_history_model = console_ns.model( controllers/console/app/message.py:message_detail_model = console_ns.model( controllers/console/app/message.py:message_infinite_scroll_pagination_model = console_ns.model( controllers/console/app/conversation.py:simple_account_model = console_ns.model( controllers/console/app/conversation.py:feedback_stat_model = console_ns.model( controllers/console/app/conversation.py:status_count_model = console_ns.model( controllers/console/app/conversation.py:message_file_model = console_ns.model( controllers/console/app/conversation.py:agent_thought_model = console_ns.model( controllers/console/app/conversation.py:simple_model_config_model = console_ns.model( controllers/console/app/conversation.py:model_config_model = console_ns.model( controllers/console/app/conversation.py:feedback_model = console_ns.model( controllers/console/app/conversation.py:annotation_model = console_ns.model( controllers/console/app/conversation.py:annotation_hit_history_model = console_ns.model( controllers/console/app/conversation.py:simple_message_detail_model = console_ns.model( controllers/console/app/conversation.py:message_detail_model = console_ns.model( controllers/console/app/conversation.py:conversation_fields_model = console_ns.model( controllers/console/app/conversation.py:conversation_pagination_model = console_ns.model( controllers/console/app/conversation.py:conversation_message_detail_model = console_ns.model( controllers/console/app/conversation.py:conversation_with_summary_model = console_ns.model( controllers/console/app/conversation.py:conversation_with_summary_pagination_model = console_ns.model( controllers/console/app/conversation.py:conversation_detail_model = console_ns.model( controllers/console/app/site.py:app_site_model = console_ns.model("AppSite", app_site_fields) controllers/console/app/mcp_server.py:app_server_model = console_ns.model("AppServer", app_server_fields) controllers/console/app/app_import.py:leaked_dependency_model = console_ns.model("LeakedDependency", leaked_dependency_fields) controllers/console/app/app_import.py:app_import_model = console_ns.model("AppImport", app_import_fields) controllers/console/app/app_import.py:app_import_check_dependencies_model = console_ns.model( controllers/console/app/model_config.py: console_ns.model( controllers/console/app/conversation_variables.py:conversation_variable_model = console_ns.model("ConversationVariable", conversation_variable_fields) controllers/console/app/conversation_variables.py:paginated_conversation_variable_model = console_ns.model( controllers/console/app/annotation.py: console_ns.model("AnnotationList", {"data": fields.List(fields.Nested(build_annotation_model(console_ns)))}), controllers/console/app/annotation.py: console_ns.model( controllers/console/app/annotation.py: fields.Nested(console_ns.model("AnnotationHitHistoryItem", annotation_hit_history_fields)) controllers/console/app/workflow_run.py:simple_account_model = console_ns.model("SimpleAccount", simple_account_fields) controllers/console/app/workflow_run.py:simple_end_user_model = console_ns.model("SimpleEndUser", simple_end_user_fields) controllers/console/app/workflow_run.py:workflow_run_for_list_model = console_ns.model("WorkflowRunForList", workflow_run_for_list_fields_copy) controllers/console/app/workflow_run.py:advanced_chat_workflow_run_for_list_model = console_ns.model( controllers/console/app/workflow_run.py:workflow_run_detail_model = console_ns.model("WorkflowRunDetail", workflow_run_detail_fields_copy) controllers/console/app/workflow_run.py:workflow_run_node_execution_model = console_ns.model( controllers/console/app/workflow_run.py:workflow_run_count_model = console_ns.model("WorkflowRunCount", workflow_run_count_fields) controllers/console/app/workflow_run.py:advanced_chat_workflow_run_pagination_model = console_ns.model( controllers/console/app/workflow_run.py:workflow_run_pagination_model = console_ns.model("WorkflowRunPagination", workflow_run_pagination_fields_copy) controllers/console/app/workflow_run.py:workflow_run_node_execution_list_model = console_ns.model( controllers/console/app/workflow_run.py:workflow_run_export_fields = console_ns.model( controllers/console/app/workflow_draft_variable.py:workflow_draft_variable_without_value_model = console_ns.model( controllers/console/app/workflow_draft_variable.py:workflow_draft_variable_model = console_ns.model("WorkflowDraftVariable", _WORKFLOW_DRAFT_VARIABLE_FIELDS) controllers/console/app/workflow_draft_variable.py:workflow_draft_env_variable_model = console_ns.model("WorkflowDraftEnvVariable", _WORKFLOW_DRAFT_ENV_VARIABLE_FIELDS) controllers/console/app/workflow_draft_variable.py:workflow_draft_env_variable_list_model = console_ns.model( controllers/console/app/workflow_draft_variable.py:workflow_draft_variable_list_without_value_model = console_ns.model( controllers/console/app/workflow_draft_variable.py:workflow_draft_variable_list_model = console_ns.model( controllers/console/app/workflow.py:simple_account_model = console_ns.model("SimpleAccount", simple_account_fields) controllers/console/app/workflow.py:conversation_variable_model = console_ns.model( controllers/console/app/workflow.py:pipeline_variable_model = console_ns.model("PipelineVariable", pipeline_variable_fields) controllers/console/app/workflow.py:workflow_model = console_ns.model("Workflow", workflow_fields_copy) controllers/console/app/workflow.py:workflow_pagination_model = console_ns.model("WorkflowPagination", workflow_pagination_fields_copy) controllers/console/app/workflow.py: console_ns.model( controllers/console/app/workflow.py: console_ns.model( ```
Author
Owner

@asukaminato0721 commented on GitHub (Feb 2, 2026):

• Here’s a practical roadmap based on the current inventory: 46 ns.model(...) usages across 25 files.

Recommended sequence (low‑risk → high‑risk):

  • Phase 1: Inline one‑off response wrappers (lowest fan‑out)
    • controllers/console/workspace/endpoint.py (Endpoint*Response)
    • controllers/console/auth/forgot_password.py
    • controllers/console/auth/data_source_oauth.py
    • controllers/console/app/audio.py
    • controllers/console/app/message.py
  • Phase 2: Small leaf DTOs in fields/ that aren’t deeply nested
    • fields/tag_fields.py
    • fields/member_fields.py
    • fields/end_user_fields.py
    • fields/annotation_fields.py
  • Phase 3: Simple controller‑scoped models
    • controllers/console/extension.py
    • controllers/console/apikey.py
    • controllers/console/app/site.py
    • controllers/console/app/mcp_server.py
    • controllers/console/app/app_import.py
    • controllers/console/workspace/account.py
    • controllers/console/app/conversation_variables.py
    • fields/conversation_variable_fields.py
  • Phase 4: Workflow draft variables (moderate nesting)
    • controllers/console/app/workflow_draft_variable.py
  • Phase 5: Workflow run + app log models (heavier, shared)
    • fields/workflow_run_fields.py
    • fields/workflow_app_log_fields.py
    • controllers/console/app/workflow_run.py
    • controllers/console/app/workflow.py
    • controllers/service_api/app/workflow.py
  • Phase 6: Annotation list + hit history (most nested/complex)
    • controllers/console/app/annotation.py
    • controllers/service_api/app/annotation.py
@asukaminato0721 commented on GitHub (Feb 2, 2026): • Here’s a practical roadmap based on the current inventory: 46 ns.model(...) usages across 25 files. Recommended sequence (low‑risk → high‑risk): - Phase 1: Inline one‑off response wrappers (lowest fan‑out) - controllers/console/workspace/endpoint.py (Endpoint*Response) - controllers/console/auth/forgot_password.py - controllers/console/auth/data_source_oauth.py - controllers/console/app/audio.py - controllers/console/app/message.py - Phase 2: Small leaf DTOs in fields/ that aren’t deeply nested - fields/tag_fields.py - fields/member_fields.py - fields/end_user_fields.py - fields/annotation_fields.py - Phase 3: Simple controller‑scoped models - controllers/console/extension.py - controllers/console/apikey.py - controllers/console/app/site.py - controllers/console/app/mcp_server.py - controllers/console/app/app_import.py - controllers/console/workspace/account.py - controllers/console/app/conversation_variables.py - fields/conversation_variable_fields.py - Phase 4: Workflow draft variables (moderate nesting) - controllers/console/app/workflow_draft_variable.py - Phase 5: Workflow run + app log models (heavier, shared) - fields/workflow_run_fields.py - fields/workflow_app_log_fields.py - controllers/console/app/workflow_run.py - controllers/console/app/workflow.py - controllers/service_api/app/workflow.py - Phase 6: Annotation list + hit history (most nested/complex) - controllers/console/app/annotation.py - controllers/service_api/app/annotation.py
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: langgenius/dify#20217