Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor: 更新项目结构以支持 pypi 包发布 & 版本更新 #1403

Merged
merged 10 commits into from
Feb 23, 2025

Conversation

lss233
Copy link
Owner

@lss233 lss233 commented Feb 22, 2025

这是一个比较大的改动,影响了项目的启动方式和插件的加载。

以下 Checklist 需要确认:

  • Windows 快速部署包
  • README
  • Docker 构建
  • 项目文档
  • 插件更新 @Cloxl @chuanSir123

好的,这是翻译成中文的 pull request 总结:

Sourcery 总结

重构项目以支持 PyPI 打包和版本更新。这包括重构项目布局、更新构建过程,并添加一个新的 API 端点用于检查和执行更新。这些更改还改进了 Windows 和 Docker 环境的部署过程。

新特性:

  • 增加对将项目打包和发布为 PyPI 包的支持。
  • 引入一个新的系统 API 端点,用于检查和执行更新,包括后端和 Web UI 组件。

增强:

  • 重构项目结构,使其遵循标准的 Python 包约定,从而提高可维护性和可扩展性。
  • 更新 Windows 快速启动脚本,以使用嵌入式 Python 并使用 pip 安装依赖项,从而简化部署过程。
  • 改进 Dockerfile 以使用多阶段构建来构建项目,从而减小最终镜像大小并提高安全性。
  • 通过创建一个专用的函数来进行依赖注入和配置加载,从而增强应用程序初始化过程。

构建:

  • 使用 pyproject.toml 配置项目以进行 PyPI 包构建。
  • 更新 Windows 快速启动工作流程,以构建包含嵌入式 Python 和 FFmpeg 的独立可执行文件。
  • 修改 Dockerfile 以使用多阶段构建、安装字体并复制默认数据。

CI:

  • 更新 Windows 快速启动工作流程,以下载和配置嵌入式 Python 环境、安装依赖项并打包应用程序。

部署:

  • 现在可以使用 pip 将项目部署为标准 Python 包。
  • Windows 快速启动包现在是独立的,并且更易于部署。
  • Docker 镜像更小,更安全。

杂项:

  • main.py 重命名为 entry.py 并将其移动到 kirara_ai 包中。
  • 将所有框架代码移动到 kirara_ai 包中。
  • 更新 import 语句以反映新的项目结构。
Original summary in English

Summary by Sourcery

Refactors the project to support PyPI packaging and version updates. This includes restructuring the project layout, updating the build process, and adding a new API endpoint for checking and performing updates. The changes also improve the deployment process for Windows and Docker environments.

New Features:

  • Adds support for packaging and publishing the project as a PyPI package.
  • Introduces a new system API endpoint for checking and performing updates, including backend and web UI components.

Enhancements:

  • Refactors the project structure to follow standard Python package conventions, improving maintainability and scalability.
  • Updates the Windows quickstart script to use embedded Python and install dependencies using pip, simplifying the deployment process.
  • Improves the Dockerfile to build the project using multi-stage builds, reducing the final image size and improving security.
  • Enhances the application initialization process by creating a dedicated function for dependency injection and configuration loading.

Build:

  • Configures the project for PyPI package building using pyproject.toml.
  • Updates the Windows quickstart workflow to build a self-contained executable with embedded Python and FFmpeg.
  • Modifies the Dockerfile to use multi-stage builds, install fonts, and copy default data.

CI:

  • Updates the Windows quickstart workflow to download and configure an embedded Python environment, install dependencies, and package the application.

Deployment:

  • The project can now be deployed as a standard Python package using pip.
  • The Windows quickstart package is now self-contained and easier to deploy.
  • The Docker image is smaller and more secure.

Chores:

  • Renames main.py to entry.py and moves it into the kirara_ai package.
  • Moves all framework code into the kirara_ai package.
  • Updates import statements to reflect the new project structure.

Copy link
Contributor

sourcery-ai bot commented Feb 22, 2025

## Sourcery 代码审查指南

此 Pull Request 重构了项目结构,以支持将项目发布为 PyPI 包,并简化版本更新。它更改了项目的启动方式、插件的加载方式,并更新了 Windows 快速启动构建流程。更改包括将基本包重命名为 `kirara_ai`,将文件重组到这个新结构中,并更新导入路径。Windows 快速启动现在构建一个可分发的包,并包括嵌入式 Python、FFmpeg 和 Web UI。Dockerfile 也已更新,以反映这些更改并从 PyPI 包构建项目。修改了多个文件以反映新的包名称和组织结构。此外,此 Pull Request 还包括对各种测试和配置文件的更新。

_由于更改看起来很简单,不需要可视化表示,因此未生成图表。_

### 文件级别更改

| 变更 | 详情 | 文件 |
| ------ | ------- | ----- |
| 更新了项目结构,以支持 PyPI 包发布和版本更新。 | <ul><li>项目的目录结构已重新组织,以符合 PyPI 打包标准。</li><li>已实施自动化构建流程以生成分发包。</li><li>版本控制已标准化,以方便更新和发布。</li></ul> | `.github/workflows/quickstart-windows.yml`<br/>`main.py`<br/>`Dockerfile`<br/>`pyproject.toml`<br/>`framework/workflow/core/dispatch/dispatcher.py`<br/>`framework/workflow/implementations/blocks/llm/chat.py`<br/>`framework/workflow/implementations/blocks/memory/chat_memory.py`<br/>`docker/start.sh`<br/>`framework/im/manager.py`<br/>`framework/plugin_manager/plugin_loader.py`<br/>`framework/llm/llm_manager.py`<br/>`plugins/im_telegram_adapter/adapter.py`<br/>`framework/web/app.py`<br/>`framework/workflow/implementations/blocks/im/messages.py`<br/>`framework/workflow/implementations/blocks/im/user_profile.py`<br/>`framework/workflow/implementations/blocks/memory/clear_memory.py`<br/>`framework/workflow/implementations/blocks/system/help.py`<br/>`framework/workflow/implementations/factories/default_factory.py`<br/>`framework/memory/composes/base.py`<br/>`framework/plugin_manager/plugin.py`<br/>`plugins/im_http_legacy_adapter/adapter.py`<br/>`plugins/llm_preset_adapters/gemini_adapter.py`<br/>`framework/workflow/core/dispatch/models/dispatch_rules.py`<br/>`framework/workflow/implementations/blocks/im/basic.py`<br/>`plugins/llm_preset_adapters/claude_adapter.py`<br/>`plugins/llm_preset_adapters/ollama_adapter.py`<br/>`framework/web/api/plugin/routes.py`<br/>`framework/workflow/core/dispatch/rules/base.py`<br/>`framework/workflow/core/execution/executor.py`<br/>`framework/workflow/implementations/blocks/llm/basic.py`<br/>`framework/workflow/implementations/blocks/variables/variable_blocks.py`<br/>`framework/workflow/implementations/factories/game_factory.py`<br/>`framework/workflow/implementations/factories/system_factory.py`<br/>`framework/workflow/implementations/workflows/system_workflows.py`<br/>`tests/memory/test_persistence.py`<br/>`tests/web/api/plugin/test_plugin.py`<br/>`framework/llm/llm_registry.py`<br/>`plugins/im_wecom_adapter/adapter.py`<br/>`plugins/llm_preset_adapters/__init__.py`<br/>`plugins/llm_preset_adapters/openai_adapter.py`<br/>`framework/web/api/im/routes.py`<br/>`framework/web/api/llm/routes.py`<br/>`framework/workflow/core/workflow/registry.py`<br/>`framework/workflow/implementations/blocks/game/dice.py`<br/>`framework/workflow/implementations/blocks/game/gacha.py`<br/>`framework/workflow/implementations/blocks/llm/image.py`<br/>`framework/memory/registry.py`<br/>`plugins/im_http_legacy_adapter/__init__.py`<br/>`plugins/im_telegram_adapter/__init__.py`<br/>`plugins/im_wecom_adapter/__init__.py`<br/>`framework/workflow/core/block/param.py`<br/>`framework/workflow/implementations/blocks/system/basic.py`<br/>`tests/memory/test_scope.py`<br/>`tests/utils/auth_test_utils.py`<br/>`tests/workflow_executor/test_block.py`<br/>`tests/workflow_executor/test_workflow_basic.py`<br/>`framework/config/config_loader.py`<br/>`framework/events/event.py`<br/>`framework/im/im_registry.py`<br/>`framework/ioc/inject.py`<br/>`framework/llm/format/request.py`<br/>`framework/memory/persistences/base.py`<br/>`framework/memory/persistences/codecs.py`<br/>`framework/memory/scopes/base.py`<br/>`framework/plugin_manager/plugin_event_bus.py`<br/>`plugins/im_http_legacy_adapter/tests/api_test.py`<br/>`framework/web/api/block/models.py`<br/>`framework/web/api/dispatch/models.py`<br/>`framework/web/api/im/models.py`<br/>`framework/web/api/llm/models.py`<br/>`framework/web/api/plugin/models.py`<br/>`framework/web/auth/middleware.py`<br/>`framework/workflow/core/block/base.py`<br/>`framework/workflow/core/block/schema.py`<br/>`framework/workflow/core/workflow/base.py`<br/>`tests/test_config_loader.py`<br/>`tests/utils/test_block_registry.py`<br/>`tests/web/api/llm/test_llm.py`<br/>`tests/web/api/system/test_system.py`<br/>`tests/workflow_executor/test_input_output.py` |

---

<details>
<summary>提示和命令</summary>

#### 与 Sourcery 互动

- **触发新的审查:** 在 Pull Request 上评论 `@sourcery-ai review`。
- **继续讨论:** 直接回复 Sourcery 的审查评论。
- **从审查评论生成 GitHub Issue:** 通过回复审查评论,要求 Sourcery 从该评论创建一个 Issue。您也可以回复评论并使用 `@sourcery-ai issue` 从该评论创建一个 Issue。
- **生成 Pull Request 标题:** 在 Pull Request 标题中的任何位置写入 `@sourcery-ai`,以随时生成标题。您也可以在 Pull Request 上评论 `@sourcery-ai title` 以随时(重新)生成标题。
- **生成 Pull Request 摘要:** 在 Pull Request 正文中的任何位置写入 `@sourcery-ai summary`,以随时在您想要的位置生成 PR 摘要。您也可以在 Pull Request 上评论 `@sourcery-ai summary` 以随时(重新)生成摘要。
- **生成审查指南:** 在 Pull Request 上评论 `@sourcery-ai guide` 以随时(重新)生成审查指南。
- **解决所有 Sourcery 评论:** 在 Pull Request 上评论 `@sourcery-ai resolve` 以解决所有 Sourcery 评论。如果您已经处理了所有评论并且不想再看到它们,这将非常有用。
- **驳回所有 Sourcery 审查:** 在 Pull Request 上评论 `@sourcery-ai dismiss` 以驳回所有现有的 Sourcery 审查。如果您想从新的审查开始,这将特别有用 - 不要忘记评论 `@sourcery-ai review` 以触发新的审查!
- **为 Issue 生成行动计划:** 在 Issue 上评论 `@sourcery-ai plan` 以为其生成行动计划。

#### 自定义您的体验

访问您的 [仪表板](https://app.sourcery.ai) 以:
- 启用或禁用审查功能,例如 Sourcery 生成的 Pull Request 摘要、审查指南等。
- 更改审查语言。
- 添加、删除或编辑自定义审查说明。
- 调整其他审查设置。

#### 获取帮助

- [联系我们的支持团队](mailto:support@sourcery.ai) 提出问题或反馈。
- 访问我们的 [文档](https://docs.sourcery.ai) 获取详细指南和信息。
- 通过在 [X/Twitter](https://x.com/SourceryAI)、[LinkedIn](https://www.linkedin.com/company/sourcery-ai/) 或 [GitHub](https://github.com/sourcery-ai) 上关注我们,与 Sourcery 团队保持联系。

</details>
Original review guide in English

Reviewer's Guide by Sourcery

This pull request refactors the project structure to support publishing the project as a PyPI package and simplifies version updates. It changes how the project is started, how plugins are loaded, and updates the Windows quickstart build process. The changes involve renaming the base package to kirara_ai, reorganizing files into this new structure, and updating import paths. The Windows quickstart now builds a distributable package and includes embedded Python, FFmpeg, and the web UI. The Dockerfile is also updated to reflect these changes and build the project from the PyPI package. Several files are modified to reflect the new package name and organization. Additionally, the pull request includes updates to various tests and configuration files.

No diagrams generated as the changes look simple and do not need a visual representation.

File-Level Changes

Change Details Files
Updated project structure to support PyPI package releases and version updates.
  • The project's directory structure has been reorganized to conform to PyPI packaging standards.
  • Automated build processes have been implemented to generate distribution packages.
  • Versioning has been standardized to facilitate updates and releases.
.github/workflows/quickstart-windows.yml
main.py
Dockerfile
pyproject.toml
framework/workflow/core/dispatch/dispatcher.py
framework/workflow/implementations/blocks/llm/chat.py
framework/workflow/implementations/blocks/memory/chat_memory.py
docker/start.sh
framework/im/manager.py
framework/plugin_manager/plugin_loader.py
framework/llm/llm_manager.py
plugins/im_telegram_adapter/adapter.py
framework/web/app.py
framework/workflow/implementations/blocks/im/messages.py
framework/workflow/implementations/blocks/im/user_profile.py
framework/workflow/implementations/blocks/memory/clear_memory.py
framework/workflow/implementations/blocks/system/help.py
framework/workflow/implementations/factories/default_factory.py
framework/memory/composes/base.py
framework/plugin_manager/plugin.py
plugins/im_http_legacy_adapter/adapter.py
plugins/llm_preset_adapters/gemini_adapter.py
framework/workflow/core/dispatch/models/dispatch_rules.py
framework/workflow/implementations/blocks/im/basic.py
plugins/llm_preset_adapters/claude_adapter.py
plugins/llm_preset_adapters/ollama_adapter.py
framework/web/api/plugin/routes.py
framework/workflow/core/dispatch/rules/base.py
framework/workflow/core/execution/executor.py
framework/workflow/implementations/blocks/llm/basic.py
framework/workflow/implementations/blocks/variables/variable_blocks.py
framework/workflow/implementations/factories/game_factory.py
framework/workflow/implementations/factories/system_factory.py
framework/workflow/implementations/workflows/system_workflows.py
tests/memory/test_persistence.py
tests/web/api/plugin/test_plugin.py
framework/llm/llm_registry.py
plugins/im_wecom_adapter/adapter.py
plugins/llm_preset_adapters/__init__.py
plugins/llm_preset_adapters/openai_adapter.py
framework/web/api/im/routes.py
framework/web/api/llm/routes.py
framework/workflow/core/workflow/registry.py
framework/workflow/implementations/blocks/game/dice.py
framework/workflow/implementations/blocks/game/gacha.py
framework/workflow/implementations/blocks/llm/image.py
framework/memory/registry.py
plugins/im_http_legacy_adapter/__init__.py
plugins/im_telegram_adapter/__init__.py
plugins/im_wecom_adapter/__init__.py
framework/workflow/core/block/param.py
framework/workflow/implementations/blocks/system/basic.py
tests/memory/test_scope.py
tests/utils/auth_test_utils.py
tests/workflow_executor/test_block.py
tests/workflow_executor/test_workflow_basic.py
framework/config/config_loader.py
framework/events/event.py
framework/im/im_registry.py
framework/ioc/inject.py
framework/llm/format/request.py
framework/memory/persistences/base.py
framework/memory/persistences/codecs.py
framework/memory/scopes/base.py
framework/plugin_manager/plugin_event_bus.py
plugins/im_http_legacy_adapter/tests/api_test.py
framework/web/api/block/models.py
framework/web/api/dispatch/models.py
framework/web/api/im/models.py
framework/web/api/llm/models.py
framework/web/api/plugin/models.py
framework/web/auth/middleware.py
framework/workflow/core/block/base.py
framework/workflow/core/block/schema.py
framework/workflow/core/workflow/base.py
tests/test_config_loader.py
tests/utils/test_block_registry.py
tests/web/api/llm/test_llm.py
tests/web/api/system/test_system.py
tests/workflow_executor/test_input_output.py

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!
  • Generate a plan of action for an issue: Comment @sourcery-ai plan on
    an issue to generate a plan of action for it.

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

Copy link
Contributor

@sourcery-ai sourcery-ai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@lss233 - 我已经查看了你的更改 - 这里有一些反馈:

总体评论

  • 考虑使用虚拟环境来隔离项目依赖项。
  • 这些更改涉及很多文件 - 确保你已经彻底测试了所有内容。
以下是我在审查期间查看的内容
  • 🟡 一般问题:发现 2 个问题
  • 🟢 安全性:一切看起来都不错
  • 🟡 测试:发现 1 个问题
  • 🟡 复杂性:发现 1 个问题
  • 🟢 文档:一切看起来都不错

Sourcery 对开源是免费的 - 如果你喜欢我们的评论,请考虑分享它们 ✨
帮助我更有用! 请在每条评论上点击 👍 或 👎,我将使用反馈来改进你的评论。
Original comment in English

Hey @lss233 - I've reviewed your changes - here's some feedback:

Overall Comments:

  • Consider using a virtual environment to isolate project dependencies.
  • The changes touch a lot of files - make sure you've tested everything thoroughly.
Here's what I looked at during the review
  • 🟡 General issues: 2 issues found
  • 🟢 Security: all looks good
  • 🟡 Testing: 1 issue found
  • 🟡 Complexity: 1 issue found
  • 🟢 Documentation: all looks good

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

classifiers = [
"Programming Language :: Python :: 3",
"License :: OSI Approved :: MIT License",
"Operating System :: OS Independent",
]
dependencies = [
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

suggestion: 检查是否将测试包作为运行时依赖项包含在内。

诸如“pytest”和“pytest-asyncio”之类的包通常仅在开发期间使用。 如果在运行时不需要它们,请考虑将它们移动到单独的 dev-dependencies 部分。

Original comment in English

suggestion: Review inclusion of testing packages as runtime dependencies.

Packages like 'pytest' and 'pytest-asyncio' are typically used only during development. If they aren't required at runtime, consider moving them to a separate dev-dependencies section.

from kirara_ai.entry import init_application, run_application


def main():
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

suggestion: 考虑在触发重启之前添加日志记录。

在重启期间启动新进程之前,添加日志语句将有助于跟踪应用程序的生命周期,尤其是在排除重启问题时。

建议的实施方式:

import os
import subprocess
import sys
import logging
    except SystemExit as e:
        if str(e) == "restart":
            logging.info("Restarting the application process...")
            # 重新启动程序
            process = subprocess.Popen([sys.executable, "-m", "kirara_ai"], env=os.environ, cwd=os.getcwd())
            process.wait()
Original comment in English

suggestion: Consider adding logging before triggering a restart.

Before launching the new process during a restart, adding a log statement would help in tracing the application's lifecycle, especially for troubleshooting restart issues.

Suggested implementation:

import os
import subprocess
import sys
import logging
    except SystemExit as e:
        if str(e) == "restart":
            logging.info("Restarting the application process...")
            # 重新启动程序
            process = subprocess.Popen([sys.executable, "-m", "kirara_ai"], env=os.environ, cwd=os.getcwd())
            process.wait()

@@ -76,7 +76,7 @@ async def test_get_system_status(self, test_client, auth_headers):
mock_process.cpu_percent.return_value = 1.2
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

suggestion (testing): 建议为新的 /check-update/update 端点添加测试。

此提交引入了用于检查和执行更新的新端点。 应该添加测试以确保这些端点正常运行,包括错误处理和成功场景。

建议的实施方式:

import pytest

@pytest.mark.asyncio
async def test_check_update_endpoint_success(test_client, auth_headers):
    response = await test_client.get("/backend-api/api/system/check-update", headers=auth_headers)
    assert response.status_code == 200
    json_response = await response.json()
    # Verify that the response contains a key indicating update availability.
    assert "update_available" in json_response

@pytest.mark.asyncio
async def test_update_endpoint_success(test_client, auth_headers):
    response = await test_client.post("/backend-api/api/system/update", headers=auth_headers)
    assert response.status_code == 200
    json_response = await response.json()
    # Verify the response indicates update completed successfully.
    assert json_response.get("updated", False) is True

@pytest.mark.asyncio
async def test_check_update_endpoint_unauthorized(test_client):
    # Test unauthorized access for /check-update endpoint.
    response = await test_client.get("/backend-api/api/system/check-update")
    assert response.status_code in (401, 403)

@pytest.mark.asyncio
async def test_update_endpoint_error(test_client, auth_headers):
    # Simulate an error scenario by using an incorrect HTTP method.
    response = await test_client.get("/backend-api/api/system/update", headers=auth_headers)
    # The endpoint should not allow GET, so expect a 405 Method Not Allowed or similar error.
    assert response.status_code in (405, 404)

确保端点 "/backend-api/api/system/check-update" 和 "/backend-api/api/system/update" 存在于您的主代码库中,并且它们返回测试中假设的响应。 根据需要调整 JSON 键名和响应代码以匹配实际实现。

Original comment in English

suggestion (testing): Suggest adding tests for the new /check-update and /update endpoints.

This commit introduces new endpoints for checking and performing updates. Tests should be added to ensure these endpoints function correctly, including error handling and success scenarios.

Suggested implementation:

import pytest

@pytest.mark.asyncio
async def test_check_update_endpoint_success(test_client, auth_headers):
    response = await test_client.get("/backend-api/api/system/check-update", headers=auth_headers)
    assert response.status_code == 200
    json_response = await response.json()
    # Verify that the response contains a key indicating update availability.
    assert "update_available" in json_response

@pytest.mark.asyncio
async def test_update_endpoint_success(test_client, auth_headers):
    response = await test_client.post("/backend-api/api/system/update", headers=auth_headers)
    assert response.status_code == 200
    json_response = await response.json()
    # Verify the response indicates update completed successfully.
    assert json_response.get("updated", False) is True

@pytest.mark.asyncio
async def test_check_update_endpoint_unauthorized(test_client):
    # Test unauthorized access for /check-update endpoint.
    response = await test_client.get("/backend-api/api/system/check-update")
    assert response.status_code in (401, 403)

@pytest.mark.asyncio
async def test_update_endpoint_error(test_client, auth_headers):
    # Simulate an error scenario by using an incorrect HTTP method.
    response = await test_client.get("/backend-api/api/system/update", headers=auth_headers)
    # The endpoint should not allow GET, so expect a 405 Method Not Allowed or similar error.
    assert response.status_code in (405, 404)

Ensure that the endpoints "/backend-api/api/system/check-update" and "/backend-api/api/system/update" exist in your main codebase and that they return the responses assumed in the tests. Adjust the JSON key names and response codes as needed to match the actual implementation.

).model_dump()


@system_bp.route("/update", methods=["POST"])
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

issue (complexity): 考虑将更新逻辑重构为专用帮助程序函数,以提高代码组织和可测试性。

考虑将更新逻辑提取到小型、专用的帮助程序函数和/或服务类中。 例如,您可以按如下方式拆分后端更新和 webui 更新逻辑:

async def perform_backend_update(data: dict, temp_dir: str) -> None:
    backend_url = data["backend_download_url"]
    backend_file, _ = await download_file(backend_url, temp_dir)
    subprocess.run([sys.executable, "-m", "pip", "install", backend_file], check=True)

async def perform_webui_update(data: dict, temp_dir: str) -> None:
    webui_url = data["webui_download_url"]
    webui_file, _ = await download_file(webui_url, temp_dir)
    static_dir = current_app.static_folder
    with tarfile.open(webui_file, "r:gz") as tar:
        for member in tar.getmembers():
            if member.name.startswith("package/dist/"):
                member.name = member.name[len("package/dist/"):]
                tar.extract(member, path=static_dir)

然后更新您的端点以委派职责:

@system_bp.route("/update", methods=["POST"])
@require_auth
async def perform_update():
    data = await request.get_json()
    temp_dir = tempfile.mkdtemp()
    try:
        if data.get("update_backend", False):
            await perform_backend_update(data, temp_dir)
        if data.get("update_webui", False):
            await perform_webui_update(data, temp_dir)
        return {"status": "success", "message": "更新完成"}
    except Exception as e:
        return {"status": "error", "message": str(e)}, 500
    finally:
        shutil.rmtree(temp_dir)

这种重构隔离了关注点,使端点更易于遵循和测试,同时保持功能完整。

Original comment in English

issue (complexity): Consider refactoring the update logic into dedicated helper functions to improve code organization and testability.

Consider extracting the update logic into small, dedicated helper functions and/or service classes. For example, you can split the backend update and webui update logic as follows:

async def perform_backend_update(data: dict, temp_dir: str) -> None:
    backend_url = data["backend_download_url"]
    backend_file, _ = await download_file(backend_url, temp_dir)
    subprocess.run([sys.executable, "-m", "pip", "install", backend_file], check=True)

async def perform_webui_update(data: dict, temp_dir: str) -> None:
    webui_url = data["webui_download_url"]
    webui_file, _ = await download_file(webui_url, temp_dir)
    static_dir = current_app.static_folder
    with tarfile.open(webui_file, "r:gz") as tar:
        for member in tar.getmembers():
            if member.name.startswith("package/dist/"):
                member.name = member.name[len("package/dist/"):]
                tar.extract(member, path=static_dir)

Then update your endpoint to delegate the responsibilities:

@system_bp.route("/update", methods=["POST"])
@require_auth
async def perform_update():
    data = await request.get_json()
    temp_dir = tempfile.mkdtemp()
    try:
        if data.get("update_backend", False):
            await perform_backend_update(data, temp_dir)
        if data.get("update_webui", False):
            await perform_webui_update(data, temp_dir)
        return {"status": "success", "message": "更新完成"}
    except Exception as e:
        return {"status": "error", "message": str(e)}, 500
    finally:
        shutil.rmtree(temp_dir)

This refactoring isolates concerns, making the endpoint easier to follow and test while keeping functionality intact.

…rovements

- Add CLI entry point in pyproject.toml
- Update dispatch rules to use more flexible matching
- Improve workflow creation with description support
- Add system configuration management endpoints
- Implement update registry configuration
- Modify memory composition and logging
- Enhance plugin and system update mechanisms
@lss233 lss233 merged commit 552ac3a into refactoring-v3-mvp Feb 23, 2025
2 checks passed
@lss233 lss233 deleted the feature/pypi_distribution branch February 23, 2025 09:20
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant