Skip to content

Conversation

@molanp
Copy link
Owner

@molanp molanp commented Jan 15, 2026

  • 为MCSMAPI类添加@Property装饰器,使overview、instance、user、daemon、file、image等方法可以作为属性访问,
    简化了调用方式。同时删除了多余的括号调用,在examples中更新了所有相关调用方式。

  • resolve [Feature Request]: 计划任务管理
    Fixes [Feature Request]: 计划任务管理 #17

BREAKING CHANGE: 原来的mcsm.daemon()、mcsm.instance()等调用方式需要改为mcsm.daemon、mcsm.instance

由 Sourcery 生成的摘要

重构核心 API 入口点,将方法调用改为属性访问,并引入实例计划任务管理功能。

新功能:

  • 添加计划任务模型和 API,用于管理实例的计划任务,包括从实例中列出、创建、更新和删除计划任务。
  • 通过新的调度 API 暴露一个实例方法,以获取关联的计划任务。

错误修复:

  • 将文件复制操作统一到一致的 copy_to 命名下,避免不同复制辅助函数之间的混淆。

增强改进:

  • 为守护进程模型扩展额外的配置信息和系统信息字段,并更新守护进程创建逻辑以接受带类型的配置对象。
  • 简化 MCSMAPI 的使用方式,使 overviewinstanceuserdaemonfileimage 可作为属性访问而非方法调用,并相应更新示例。
  • 明确 token 使用文档,并清理冗余的方法文档字符串。
  • 调整实例、用户和总览流程的示例,改为使用新的基于属性的 API 以及精简后的文件操作。

构建:

  • 将包版本提升至 0.1.8,以包含新的调度功能和 API 变更。
Original summary in English

Summary by Sourcery

重构核心 API 入口点以使用基于属性的访问方式,并引入实例计划任务管理能力。

新功能:

  • 添加计划任务模型和相关 API,用于管理实例上的计划任务,包括列出、创建、更新和从实例中删除任务。
  • 通过新的计划任务 API 暴露实例级辅助方法,用于列出和创建计划任务。

错误修复:

  • 统一文件复制操作,使用统一的 copy_to 命名,以避免不同复制辅助方法之间的混淆。

增强改进:

  • 为守护进程配置和系统信息模型扩展额外字段,并在守护进程创建 API 中复用守护进程配置类型。
  • 简化 MCSMAPI 的使用方式,将 overview、instance、user、daemon、file 和 image 从方法改为属性访问,并相应更新示例代码。
  • 明确 token 的使用语义,精简冗余的与请求相关的文档字符串。
  • 精简实例、用户、守护进程和总览等示例脚本,使其与新的基于属性的 API 和更新后的文件操作保持一致。

构建:

  • 将包版本提升到 0.1.8,以体现新的计划任务功能和 API 变更。
Original summary in English

Summary by Sourcery

Refactor the core API entrypoints to use attribute-based access and introduce instance schedule management capabilities.

New Features:

  • Add schedule models and APIs to manage instance schedules, including listing, creating, updating, and deleting tasks from an instance.
  • Expose instance-level helpers to list and create schedules via the new schedule API.

Bug Fixes:

  • Standardize file copy operations under a single copy_to naming to avoid confusion between different copy helpers.

Enhancements:

  • Extend daemon configuration and system info models with additional fields and reuse the daemon configuration type in the daemon creation API.
  • Simplify MCSMAPI usage by making overview, instance, user, daemon, file, and image accessible as properties instead of methods, and update examples accordingly.
  • Clarify token usage semantics and trim redundant request-related docstrings.
  • Streamline example scripts for instances, users, daemons, and overviews to match the new attribute-based API and updated file operations.

Build:

  • Bump package version to 0.1.8 to reflect the new schedule features and API changes.

- 为MCSMAPI类添加@Property装饰器,使overview、instance、user、daemon、file、image等方法可以作为属性访问,
简化了调用方式。同时删除了多余的括号调用,在examples中更新了所有相关调用方式。

- resolve [Feature Request]: 计划任务管理
Fixes #17

BREAKING CHANGE: 原来的mcsm.daemon()、mcsm.instance()等调用方式需要改为mcsm.daemon、mcsm.instance
@sourcery-ai
Copy link
Contributor

sourcery-ai bot commented Jan 15, 2026

审阅者指南

将核心 MCSMAPI 入口从可调用方法重构为属性,引入完整的调度模型和用于管理实例计划任务的 API,丰富守护进程模型和示例以使用类型化配置,统一文件复制命名,并将包版本提升到 0.1.8。

使用新 Schedule API 进行实例计划管理的时序图

sequenceDiagram
    actor Client
    participant MCSMAPI
    participant Instance
    participant ScheduleAPI as Schedule
    participant Request
    participant MCSMPanel as MCSMPanelScheduleEndpoint

    Client->>MCSMAPI: api = MCSMAPI(base_url)
    Client->>MCSMAPI: instance = api.instance
    Client->>Instance: schedules = instance.list_schedule()

    Instance->>ScheduleAPI: list(daemonId, instanceUuid)
    ScheduleAPI->>Request: send("GET", ApiPool.SCHEDULE, params)
    Request->>MCSMPanel: HTTP GET /api/protected_schedule
    MCSMPanel-->>Request: schedule list JSON
    Request-->>ScheduleAPI: list of dict
    ScheduleAPI-->>Instance: list of ScheduleDetail
    Instance-->>Client: list of ScheduleDetail

    Client->>Instance: create_schedule(config)
    Instance->>ScheduleAPI: create(daemonId, instanceUuid, config)
    ScheduleAPI->>Request: send("POST", ApiPool.SCHEDULE, params, data)
    Request->>MCSMPanel: HTTP POST /api/protected_schedule
    MCSMPanel-->>Request: success flag
    Request-->>ScheduleAPI: bool
    ScheduleAPI-->>Instance: bool
    Instance-->>Client: bool
Loading

新调度模型和 API 的类图

classDiagram
    class ScheduleActionType {
        <<enumeration>>
        COMMAND
        DELAY
        STOP
        START
        RESTART
        KILL
    }

    class ScheduleType {
        <<enumeration>>
        INTERVAL
        CYCLE
        SPECIFY
    }

    class ScheduleAction {
        +ScheduleActionType type
        +str payload
    }

    class SchedulePostBody {
        +str name
        +int count
        +str time
        +list~ScheduleAction~ actions
        +ScheduleType type
    }

    class ScheduleDetail {
        +str instanceUuid
        +str daemonId
        +bool delete()
        +bool update(config SchedulePostBody)
    }

    class Schedule {
        +list~ScheduleDetail~ list(daemonId str, uuid str)
        +bool delete(daemonId str, uuid str, task_name str)
        +bool create(daemonId str, uuid str, config SchedulePostBody)
        +bool update(daemonId str, uuid str, config SchedulePostBody)
    }

    class Instance {
        +str daemonId
        +str instanceUuid
        +list~ScheduleDetail~ list_schedule()
        +bool create_schedule(config SchedulePostBody)
    }

    ScheduleAction --> ScheduleActionType
    SchedulePostBody --> ScheduleType
    SchedulePostBody "1" --> "*" ScheduleAction : actions
    ScheduleDetail --|> SchedulePostBody
    Instance ..> Schedule : uses
    Instance --> ScheduleDetail : returns
Loading

更新后的守护进程模型和 MCSMAPI 入口的类图

classDiagram
    class MCSMAPI {
        +str mcsm_url
        +str authentication
        +overview
        +instance
        +user
        +daemon
        +file
        +image
        +login(username str, password str) MCSMAPI
        +login_with_apikey(apikey str) MCSMAPI
    }

    class Overview
    class Instance
    class User
    class Daemon
    class File
    class Image

    MCSMAPI --> Overview : overview
    MCSMAPI --> Instance : instance
    MCSMAPI --> User : user
    MCSMAPI --> Daemon : daemon
    MCSMAPI --> File : file
    MCSMAPI --> Image : image

    class DaemonSetting {
        +int port
        +int maxDownloadFromUrlFileCount
    }

    class DaemonOperation {
        +str id
        +str ip
        +int port
        +str prefix
        +str remarks
    }

    class DaemonConfig {
        +str ip
        +int port
        +str prefix
        +str remarks
        +str apiKey
    }

    class DaemonSystemInfo {
        +str version
        +ProcessInfo process
        +InstanceStat instance
        +SystemInfo system
        +list~CpuMemChart~ cpuMemChart
        +DaemonSetting config
        +bool available
        +str ip
        +int port
        +str prefix
        +str remarks
    }

    class DaemonApi {
        +list~DaemonSystemInfo~ system()
        +str add(config DaemonConfig)
        +bool delete(daemonId str)
    }

    DaemonSystemInfo --|> DaemonOperation
    DaemonSystemInfo --> DaemonSetting
    DaemonApi --> DaemonSystemInfo : returns
    DaemonApi --> DaemonConfig : accepts
Loading

文件级更改

Change Details Files
将 MCSMAPI 上的核心 API 入口以属性而非方法的形式暴露出来,并相应更新所有示例。
  • 在 MCSMAPI 上为 overview、instance、user、daemon、file 和 image 添加 @Property 访问器,使其在无需加括号的情况下返回各自的 API 对象。
  • 更新示例脚本以使用属性访问(例如 mcsm.daemon、mcsm.instance、mcsm.user、mcsm.overview),并简化部分示例流程(例如返回字典推导式、移除不必要的写入)。
  • 调整用户和实例示例以复用管理对象,而不是反复调用工厂方法。
mcsmapi/__init__.py
example/daemon.py
example/overview.py
example/instance.py
example/user.py
example/use_case/get_all_instance_info.py
example/use_case/search_instance_by_name.py
引入计划管理模型和 API,并将其接入 Instance 模型。
  • 添加 ScheduleActionType、ScheduleType、ScheduleAction、SchedulePostBody 和 ScheduleDetail 的 Pydantic 模型,用于表示计划配置和任务,并包含删除和更新的辅助方法。
  • 创建 Schedule API,在新的 ApiPool.SCHEDULE 端点上提供 list、create、update 和 delete 操作。
  • 添加 Instance.list_schedule 和 Instance.create_schedule 便捷方法,通过实例的 daemonId 和 UUID 调用 Schedule API。
mcsmapi/models/schedule.py
mcsmapi/apis/schedule.py
mcsmapi/models/instance.py
mcsmapi/pool.py
使用更丰富的配置/系统信息扩展守护进程模型,并在 Daemon API 和示例中使用类型化配置。
  • 修改 DaemonSetting 以包含 maxDownloadFromUrlFileCount,并重构 DaemonSystemInfo,使其继承自 DaemonOperation,增加可用性、网络和元数据字段,并将 config 设为可选。
  • 更新 Daemon.add 以直接接收 DaemonConfig 实例,并移除方法内部从 dict 到模型的转换。
  • 调整守护进程示例,在添加节点时显式构造 DaemonConfig,并在概览示例中适配新的 DaemonSystemInfo 结构(例如处理 available 标志)。
mcsmapi/models/daemon.py
mcsmapi/apis/daemon.py
example/daemon.py
example/overview.py
将文件复制操作统一为 copy_to 命名,并在 API 和示例中进行同步更新。
  • 在文件 API 中将 File.copy 重命名为 File.copy_to,并更新 File.copyOne 以调用新的 copy_to 方法。
  • 将模型层的 File.copy2 辅助方法重命名为 copy_to 以保持一致性。
  • 更新示例中对文件复制的调用,从 copy 改为 copy_to。
mcsmapi/apis/file.py
mcsmapi/models/file.py
example/instance.py
整理请求/令牌处理和项目元数据。
  • 为 Request.token 属性补充文档,说明其需要与 Cookie 匹配,并移除 Request setter 上多余的 docstring。
  • 将 pyproject.toml 中项目版本从 0.1.8.b4 提升为 0.1.8,以反映调度功能集已定版。
mcsmapi/request.py
pyproject.toml

与关联 Issue 的对照评估

Issue Objective Addressed Explanation
#17 通过 /api/protected_schedule 端点,使用 daemonIduuid(token 由全局处理),在客户端支持列出实例计划任务,并返回结构化的计划数据。
#17 在客户端支持通过 DELETE /api/protected_schedule,使用 daemonIduuidtask_name 删除实例计划任务。
#17 在客户端支持通过 POST /api/protected_schedule,使用指定的请求体结构(name、count、type、time、actions)创建和更新实例计划任务,并包含相应模型。

可能关联的 Issue


技巧和命令

与 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 来触发新的审查!

自定义你的体验

访问你的 dashboard 以:

  • 启用或禁用审查功能,例如 Sourcery 生成的 pull request 摘要、审阅者指南等。
  • 更改审查语言。
  • 添加、移除或编辑自定义审查指令。
  • 调整其他审查设置。

获取帮助

Original review guide in English

Reviewer's Guide

Refactors the core MCSMAPI entrypoints to be property-based instead of callable methods, introduces a full scheduling model and API for managing instance scheduled tasks, enriches daemon models and examples to use typed configs, unifies file copy naming, and bumps the package to 0.1.8.

Sequence diagram for instance schedule management via new Schedule API

sequenceDiagram
    actor Client
    participant MCSMAPI
    participant Instance
    participant ScheduleAPI as Schedule
    participant Request
    participant MCSMPanel as MCSMPanelScheduleEndpoint

    Client->>MCSMAPI: api = MCSMAPI(base_url)
    Client->>MCSMAPI: instance = api.instance
    Client->>Instance: schedules = instance.list_schedule()

    Instance->>ScheduleAPI: list(daemonId, instanceUuid)
    ScheduleAPI->>Request: send("GET", ApiPool.SCHEDULE, params)
    Request->>MCSMPanel: HTTP GET /api/protected_schedule
    MCSMPanel-->>Request: schedule list JSON
    Request-->>ScheduleAPI: list of dict
    ScheduleAPI-->>Instance: list of ScheduleDetail
    Instance-->>Client: list of ScheduleDetail

    Client->>Instance: create_schedule(config)
    Instance->>ScheduleAPI: create(daemonId, instanceUuid, config)
    ScheduleAPI->>Request: send("POST", ApiPool.SCHEDULE, params, data)
    Request->>MCSMPanel: HTTP POST /api/protected_schedule
    MCSMPanel-->>Request: success flag
    Request-->>ScheduleAPI: bool
    ScheduleAPI-->>Instance: bool
    Instance-->>Client: bool
Loading

Class diagram for new schedule models and APIs

classDiagram
    class ScheduleActionType {
        <<enumeration>>
        COMMAND
        DELAY
        STOP
        START
        RESTART
        KILL
    }

    class ScheduleType {
        <<enumeration>>
        INTERVAL
        CYCLE
        SPECIFY
    }

    class ScheduleAction {
        +ScheduleActionType type
        +str payload
    }

    class SchedulePostBody {
        +str name
        +int count
        +str time
        +list~ScheduleAction~ actions
        +ScheduleType type
    }

    class ScheduleDetail {
        +str instanceUuid
        +str daemonId
        +bool delete()
        +bool update(config SchedulePostBody)
    }

    class Schedule {
        +list~ScheduleDetail~ list(daemonId str, uuid str)
        +bool delete(daemonId str, uuid str, task_name str)
        +bool create(daemonId str, uuid str, config SchedulePostBody)
        +bool update(daemonId str, uuid str, config SchedulePostBody)
    }

    class Instance {
        +str daemonId
        +str instanceUuid
        +list~ScheduleDetail~ list_schedule()
        +bool create_schedule(config SchedulePostBody)
    }

    ScheduleAction --> ScheduleActionType
    SchedulePostBody --> ScheduleType
    SchedulePostBody "1" --> "*" ScheduleAction : actions
    ScheduleDetail --|> SchedulePostBody
    Instance ..> Schedule : uses
    Instance --> ScheduleDetail : returns
Loading

Class diagram for updated daemon models and MCSMAPI entrypoints

classDiagram
    class MCSMAPI {
        +str mcsm_url
        +str authentication
        +overview
        +instance
        +user
        +daemon
        +file
        +image
        +login(username str, password str) MCSMAPI
        +login_with_apikey(apikey str) MCSMAPI
    }

    class Overview
    class Instance
    class User
    class Daemon
    class File
    class Image

    MCSMAPI --> Overview : overview
    MCSMAPI --> Instance : instance
    MCSMAPI --> User : user
    MCSMAPI --> Daemon : daemon
    MCSMAPI --> File : file
    MCSMAPI --> Image : image

    class DaemonSetting {
        +int port
        +int maxDownloadFromUrlFileCount
    }

    class DaemonOperation {
        +str id
        +str ip
        +int port
        +str prefix
        +str remarks
    }

    class DaemonConfig {
        +str ip
        +int port
        +str prefix
        +str remarks
        +str apiKey
    }

    class DaemonSystemInfo {
        +str version
        +ProcessInfo process
        +InstanceStat instance
        +SystemInfo system
        +list~CpuMemChart~ cpuMemChart
        +DaemonSetting config
        +bool available
        +str ip
        +int port
        +str prefix
        +str remarks
    }

    class DaemonApi {
        +list~DaemonSystemInfo~ system()
        +str add(config DaemonConfig)
        +bool delete(daemonId str)
    }

    DaemonSystemInfo --|> DaemonOperation
    DaemonSystemInfo --> DaemonSetting
    DaemonApi --> DaemonSystemInfo : returns
    DaemonApi --> DaemonConfig : accepts
Loading

File-Level Changes

Change Details Files
Expose core API entrypoints on MCSMAPI as properties instead of methods and update all examples accordingly.
  • Add @Property accessors for overview, instance, user, daemon, file, and image on MCSMAPI so they return their respective API objects without needing parentheses.
  • Update example scripts to use property access (e.g., mcsm.daemon, mcsm.instance, mcsm.user, mcsm.overview) and simplify some example flows (e.g., return dict comprehensions, remove unnecessary writes).
  • Adjust user and instance examples to reuse manager objects instead of repeatedly calling factory methods.
mcsmapi/__init__.py
example/daemon.py
example/overview.py
example/instance.py
example/user.py
example/use_case/get_all_instance_info.py
example/use_case/search_instance_by_name.py
Introduce schedule management models and APIs and wire them into the Instance model.
  • Add ScheduleActionType, ScheduleType, ScheduleAction, SchedulePostBody, and ScheduleDetail Pydantic models representing schedule configuration and tasks, including helper methods for delete and update.
  • Create a Schedule API with list, create, update, and delete operations against the new ApiPool.SCHEDULE endpoint.
  • Add Instance.list_schedule and Instance.create_schedule convenience methods that call the Schedule API with the instance’s daemonId and UUID.
mcsmapi/models/schedule.py
mcsmapi/apis/schedule.py
mcsmapi/models/instance.py
mcsmapi/pool.py
Extend daemon models with richer configuration/system info and use typed configuration in the Daemon API and examples.
  • Change DaemonSetting to include maxDownloadFromUrlFileCount and rework DaemonSystemInfo to inherit from DaemonOperation, add availability, network and metadata fields, and make config optional.
  • Update Daemon.add to accept a DaemonConfig instance directly and remove dict-to-model conversion inside the method.
  • Adjust daemon example to construct DaemonConfig explicitly when adding a node and to work with the new DaemonSystemInfo shape in overview examples (e.g., handling available flag).
mcsmapi/models/daemon.py
mcsmapi/apis/daemon.py
example/daemon.py
example/overview.py
Normalize file copy operations under a copy_to naming and propagate this to APIs and examples.
  • Rename File.copy to File.copy_to in the file API and update File.copyOne to call the new copy_to method.
  • Rename the model-level File.copy2 helper to copy_to for consistency.
  • Update example usage of file copying to call copy_to instead of copy.
mcsmapi/apis/file.py
mcsmapi/models/file.py
example/instance.py
Tidy request/token handling and project metadata.
  • Add documentation to the Request.token attribute about needing to match cookies and remove redundant docstrings from Request setters.
  • Bump the project version from 0.1.8.b4 to 0.1.8 in pyproject.toml to reflect the finalized scheduling feature set.
mcsmapi/request.py
pyproject.toml

Assessment against linked issues

Issue Objective Addressed Explanation
#17 Add client-side support to list instance scheduled tasks via the /api/protected_schedule endpoint using daemonId, uuid (and token handled globally), returning structured schedule data.
#17 Add client-side support to delete an instance scheduled task via DELETE /api/protected_schedule with daemonId, uuid, and task_name.
#17 Add client-side support to create and update instance scheduled tasks via POST /api/protected_schedule with the specified body schema (name, count, type, time, actions), including appropriate models.

Possibly linked issues


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!

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.

Hey - 我发现了 5 个问题,并留下了一些高层次反馈:

  • example/use_case/get_all_instance_info.py 中,json.dump 已经会将内容写入文件并返回 None,因此把返回值赋给 content、对其进行断言,然后再调用 f.write(content) 要么会失败,要么会写入字符串 "None";可以简化为单行 json.dump(instance_info, f, indent=4),不需要 contentf.write
  • File.copy/File.copy2 重命名为 copy_to(以及对应示例代码的修改)是一个破坏性变更,和 mcsm.instance()mcsm.instance 的重构类似;建议新增一个已弃用的 copy 包装器,在一到两个版本中转发到 copy_to,以便依赖旧名称的现有调用方更平滑地迁移。
给 AI Agent 的提示词
请根据这次代码评审中的评论进行修改:

## 总体评论
-`example/use_case/get_all_instance_info.py` 中,`json.dump` 已经会将内容写入文件并返回 `None`,因此把返回值赋给 `content`、对其进行断言,然后再调用 `f.write(content)` 要么会失败,要么会写入字符串 `"None"`;可以简化为单行 `json.dump(instance_info, f, indent=4)`,不需要 `content``f.write`-`File.copy`/`File.copy2` 重命名为 `copy_to`(以及对应示例代码的修改)是一个破坏性变更,和 `mcsm.instance()``mcsm.instance` 的重构类似;建议新增一个已弃用的 `copy` 包装器,在一到两个版本中转发到 `copy_to`,以便依赖旧名称的现有调用方更平滑地迁移。

## 逐条评论

### 评论 1
<location> `mcsmapi/models/schedule.py:42` </location>
<code_context>
+    """动作参数"""
+
+
+class SchedulePostBody(BaseModel):
+    """计划任务配置参数"""
+
</code_context>

<issue_to_address>
**issue (bug_risk):** SchedulePostBody 似乎缺少一个 `instanceUuid` 字段,而文档字符串中有相关暗示。

在 `name: str` 之前的独立文档字符串 `"""实例uuid"""` 表明 `SchedulePostBody` 应该包含一个 `instanceUuid` 字段。目前在创建/更新时从未发送实例 UUID,因此后端无法知道应该把计划任务关联到哪个实例上。请添加 `instanceUuid: str` 字段(如果 API 需要的话,也请添加 `daemonId`),以便请求载荷包含完整上下文。
</issue_to_address>

### 评论 2
<location> `mcsmapi/models/schedule.py:71-80` </location>
<code_context>
+
+        return Schedule.delete(self.daemonId, self.instanceUuid, self.name)
+
+    def update(self, config: SchedulePostBody):
+        """
+        更新计划任务
+
+        :param config: 计划任务配置
+
+        :returns: 是否成功
+        """
+        from mcsmapi.apis.schedule import Schedule
+
+        return Schedule.update(config)
</code_context>

<issue_to_address>
**issue (bug_risk):** ScheduleDetail.update 没有使用实例自身的标识符,可能导致更新请求信息不完整。

`ScheduleDetail` 已经有 `instanceUuid``daemonId`,但 `update` 忽略了它们,只把 `config` 转发给 `Schedule.update`。如果 API 期望这些标识符(就像 `delete`/`list` 那样),那么该请求可能不完整,并迫使调用方在 `config` 中重复传入它们。建议在 `update` 中使用 `self.daemonId` / `self.instanceUuid`(并在需要时调整 `SchedulePostBody`),或者引入一个始终包含这些标识符的请求类型。
</issue_to_address>

### 评论 3
<location> `mcsmapi/apis/schedule.py:43-52` </location>
<code_context>
+        )
+
+    @staticmethod
+    def create(config: SchedulePostBody) -> bool:
+        """
+        创建计划任务
+
+        :param config: 计划任务配置
+
+        :returns: 是否成功
+        """
+        return send(
+            "POST",
+            f"{ApiPool.SCHEDULE}",
+            data=config.model_dump(),
+        )
+
</code_context>

<issue_to_address>
**issue (bug_risk):** Schedule.create 只发送请求体,没有发送其他端点使用的 daemon/instance 标识符。

`list``delete` 会把 `daemonId``uuid` 作为查询参数传递,但 `create` 只发送不带标识符的 `config.model_dump()`。除非后端能从认证上下文推导出目标实例,否则这可能不足以将计划任务绑定到正确的 daemon/instance 上。建议将 `daemonId`/`instanceUuid` 添加到 `SchedulePostBody` 中,或者像 `delete` 那样通过查询参数传递。
</issue_to_address>

### 评论 4
<location> `example/use_case/get_all_instance_info.py:43-45` </location>
<code_context>
 # Optional: Save info to a file in the current directory
 with open("instance_info.json", "w") as f:
     content = json.dump(instance_info, f, indent=4)
+    assert content
     f.write(content)
</code_context>

<issue_to_address>
**issue (bug_risk):** 使用 json.dump 的返回值会导致断言失败以及写入时出现 TypeError。

`json.dump` 会直接写入文件并始终返回 `None`,因此 `assert content` 会一直失败,而 `f.write(content)` 会抛出 `TypeError`。如果想同时得到字符串和文件输出,可以使用 `json.dumps` 然后调用 `f.write(content)`;或者继续使用 `json.dump`,但移除 `content`(包括断言和额外的写入)。
</issue_to_address>

### 评论 5
<location> `mcsmapi/models/daemon.py:138-147` </location>
<code_context>
     """远程节点的apiKey"""


+class DaemonSystemInfo(DaemonOperation):
+    """节点系统信息"""
+
+    version: str
+    """远程节点版本"""
+    process: ProcessInfo
+    """远程节点的基本信息"""
+    instance: InstanceStat
+    """远程节点实例基本信息"""
+    system: SystemInfo
+    """远程节点系统信息"""
+    cpuMemChart: list[CpuMemChart]
+    """cpu和内存使用趋势"""
+    config: DaemonSetting
+    """节点系统配置信息"""
+    available: bool
+    """节点可用状态"""
+    ip: str
+    """远程节点的ip"""
+    port: int
+    """远程节点的端口"""
+    prefix: str
+    """远程节点的路径前缀"""
+    remarks: str
+    """远程节点的备注"""
+
</code_context>

<issue_to_address>
**issue:** DaemonSystemInfo 字段已经改为非可选,这可能与实际可能包含 null 值的 API 响应不匹配。

这些字段(`version``process``instance``system``cpuMemChart`)之前是可选的,现在改为必填,同时该模型继承了 `DaemonOperation`。如果后端在某些情况下返回 `null` 或遗漏其中任意字段(例如 daemon 离线/初始化阶段),Pydantic 将无法通过校验。请要么保持这些字段为可选,要么确认 API 对每个 daemon 始终返回这些字段。
</issue_to_address>

Sourcery 对开源项目是免费的——如果你觉得这个评审有帮助,欢迎分享 ✨
帮我变得更有用!请在每条评论上点 👍 或 👎,我会根据你的反馈改进后续评审。
Original comment in English

Hey - I've found 5 issues, and left some high level feedback:

  • In example/use_case/get_all_instance_info.py, json.dump already writes to the file and returns None, so assigning its result to content, asserting it, and then calling f.write(content) will either fail or write "None"; simplify to a single json.dump(instance_info, f, indent=4) without content or f.write.
  • The rename from File.copy/File.copy2 to copy_to (and the corresponding example change) is a breaking change similar to the mcsm.instance()mcsm.instance refactor; consider adding a deprecated copy wrapper that forwards to copy_to for one or two releases to ease migration for existing callers relying on the old name.
Prompt for AI Agents
Please address the comments from this code review:

## Overall Comments
- In `example/use_case/get_all_instance_info.py`, `json.dump` already writes to the file and returns `None`, so assigning its result to `content`, asserting it, and then calling `f.write(content)` will either fail or write `"None"`; simplify to a single `json.dump(instance_info, f, indent=4)` without `content` or `f.write`.
- The rename from `File.copy`/`File.copy2` to `copy_to` (and the corresponding example change) is a breaking change similar to the `mcsm.instance()``mcsm.instance` refactor; consider adding a deprecated `copy` wrapper that forwards to `copy_to` for one or two releases to ease migration for existing callers relying on the old name.

## Individual Comments

### Comment 1
<location> `mcsmapi/models/schedule.py:42` </location>
<code_context>
+    """动作参数"""
+
+
+class SchedulePostBody(BaseModel):
+    """计划任务配置参数"""
+
</code_context>

<issue_to_address>
**issue (bug_risk):** SchedulePostBody appears to be missing an `instanceUuid` field that the docstring hints at.

The standalone docstring `"""实例uuid"""` before `name: str` suggests `SchedulePostBody` should include an `instanceUuid` field. Currently the instance UUID is never sent in create/update, so the backend can’t know which instance to attach the schedule to. Please add an `instanceUuid: str` field (and `daemonId` as well if the API requires it) so the payload includes the full context.
</issue_to_address>

### Comment 2
<location> `mcsmapi/models/schedule.py:71-80` </location>
<code_context>
+
+        return Schedule.delete(self.daemonId, self.instanceUuid, self.name)
+
+    def update(self, config: SchedulePostBody):
+        """
+        更新计划任务
+
+        :param config: 计划任务配置
+
+        :returns: 是否成功
+        """
+        from mcsmapi.apis.schedule import Schedule
+
+        return Schedule.update(config)
</code_context>

<issue_to_address>
**issue (bug_risk):** ScheduleDetail.update does not use the instance’s own identifiers, which may result in incomplete update requests.

`ScheduleDetail` already has `instanceUuid` and `daemonId`, but `update` ignores them and forwards only `config` to `Schedule.update`. If the API expects these identifiers (as `delete`/`list` do), the request may be incomplete and forces callers to redundantly pass them in `config`. Prefer using `self.daemonId`/`self.instanceUuid` in `update` (and adjusting `SchedulePostBody` if needed), or introduce a request type that always includes these identifiers.
</issue_to_address>

### Comment 3
<location> `mcsmapi/apis/schedule.py:43-52` </location>
<code_context>
+        )
+
+    @staticmethod
+    def create(config: SchedulePostBody) -> bool:
+        """
+        创建计划任务
+
+        :param config: 计划任务配置
+
+        :returns: 是否成功
+        """
+        return send(
+            "POST",
+            f"{ApiPool.SCHEDULE}",
+            data=config.model_dump(),
+        )
+
</code_context>

<issue_to_address>
**issue (bug_risk):** Schedule.create sends only the body, without daemon/instance identifiers that other endpoints use.

`list` and `delete` include `daemonId` and `uuid` as query params, but `create` only posts `config.model_dump()` with no identifiers. Unless the backend derives the target instance from auth context, this may not be enough to bind the schedule to the correct daemon/instance. Consider adding `daemonId`/`instanceUuid` to `SchedulePostBody` or passing them as params like `delete`.
</issue_to_address>

### Comment 4
<location> `example/use_case/get_all_instance_info.py:43-45` </location>
<code_context>
 # Optional: Save info to a file in the current directory
 with open("instance_info.json", "w") as f:
     content = json.dump(instance_info, f, indent=4)
+    assert content
     f.write(content)
</code_context>

<issue_to_address>
**issue (bug_risk):** Using json.dump’s return value leads to an assertion failure and a TypeError on write.

`json.dump` writes directly to the file and always returns `None`, so `assert content` will always fail and `f.write(content)` will raise a `TypeError`. To get both a string and file output, use `json.dumps` and then `f.write(content)`, or keep `json.dump` and remove `content` (including the assert and extra write).
</issue_to_address>

### Comment 5
<location> `mcsmapi/models/daemon.py:138-147` </location>
<code_context>
     """远程节点的apiKey"""


+class DaemonSystemInfo(DaemonOperation):
+    """节点系统信息"""
+
+    version: str
+    """远程节点版本"""
+    process: ProcessInfo
+    """远程节点的基本信息"""
+    instance: InstanceStat
+    """远程节点实例基本信息"""
+    system: SystemInfo
+    """远程节点系统信息"""
+    cpuMemChart: list[CpuMemChart]
+    """cpu和内存使用趋势"""
+    config: DaemonSetting
+    """节点系统配置信息"""
+    available: bool
+    """节点可用状态"""
+    ip: str
+    """远程节点的ip"""
+    port: int
+    """远程节点的端口"""
+    prefix: str
+    """远程节点的路径前缀"""
+    remarks: str
+    """远程节点的备注"""
+
</code_context>

<issue_to_address>
**issue:** DaemonSystemInfo fields have been made non-optional, which may not match API responses that can contain null values.

These fields (`version`, `process`, `instance`, `system`, `cpuMemChart`) were optional before and are now required, and the model now extends `DaemonOperation`. If the backend ever returns `null` or omits any of them (e.g., for offline/initializing daemons), Pydantic will fail validation. Please either keep these as optional or confirm the API always returns all of them for every daemon.
</issue_to_address>

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.

为计划任务的创建和更新方法添加daemonId和uuid参数,
使接口调用更加明确和一致。

fix(daemon): 改进节点系统信息模型定义

将DaemonSystemInfo模型中的字段改为可选类型,改进文档字符串描述,
使节点信息处理更加灵活。

refactor(instance): 优化实例信息获取逻辑

重构get_all_instance_info函数,使用字典推导式简化代码,
移除不必要的断言和文件写入操作。

feat(instance): 添加实例计划任务创建功能

在InstanceDetail类中添加create_schedule方法,
方便通过实例对象直接创建计划任务。

refactor(overview): 优化节点可用性检查逻辑

使用海象运算符简化节点可用性检查,添加类型忽略注释,
提高代码可读性。
@molanp
Copy link
Owner Author

molanp commented Jan 15, 2026

@sourcery-ai review

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.

Hey - 我在这里给出了一些总体反馈:

  • 在 schedule API 中,Schedule.createSchedule.update 的实现是完全相同的(相同的 HTTP 方法、URL 和参数);建议将它们合并为一个公共的辅助函数以避免重复,或者如果后端在创建与更新时期望有不同的行为,则在 HTTP 语义上加以区分。
  • example/overview.py 中,新加的 if ava := remote.available: 以及后面几个 # type: ignore 标记可以通过直接检查实际可选字段来清理掉(例如:if remote.available and remote.system is not None:),同时去掉未使用的 ava 变量绑定,以保持示例在类型上更安全并且更清晰。
给 AI 代理的提示
Please address the comments from this code review:

## Overall Comments
- In the schedule API, `Schedule.create` and `Schedule.update` have identical implementations (same HTTP method, URL, and params); consider consolidating them into a single helper to avoid duplication or differentiating the HTTP semantics if the backend expects different behavior for creation vs update.
- In `example/overview.py`, the new `if ava := remote.available:` plus several `# type: ignore` markers could be cleaned up by checking the actual optional fields (e.g., `if remote.available and remote.system is not None:`) and dropping the unused `ava` binding to keep the example type-safe and clearer.

Sourcery 对开源项目是免费的——如果你觉得我们的评审有帮助,欢迎分享 ✨
帮我变得更有用!请在每条评论上点击 👍 或 👎,我会根据你的反馈改进后续的评审。
Original comment in English

Hey - I've left some high level feedback:

  • In the schedule API, Schedule.create and Schedule.update have identical implementations (same HTTP method, URL, and params); consider consolidating them into a single helper to avoid duplication or differentiating the HTTP semantics if the backend expects different behavior for creation vs update.
  • In example/overview.py, the new if ava := remote.available: plus several # type: ignore markers could be cleaned up by checking the actual optional fields (e.g., if remote.available and remote.system is not None:) and dropping the unused ava binding to keep the example type-safe and clearer.
Prompt for AI Agents
Please address the comments from this code review:

## Overall Comments
- In the schedule API, `Schedule.create` and `Schedule.update` have identical implementations (same HTTP method, URL, and params); consider consolidating them into a single helper to avoid duplication or differentiating the HTTP semantics if the backend expects different behavior for creation vs update.
- In `example/overview.py`, the new `if ava := remote.available:` plus several `# type: ignore` markers could be cleaned up by checking the actual optional fields (e.g., `if remote.available and remote.system is not None:`) and dropping the unused `ava` binding to keep the example type-safe and clearer.

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.

移除example/overview.py中的海象操作符(Available assignment operator),
使代码更加清晰易读。

优化mcsmapi/apis/schedule.py中的Schedule.create方法调用,
直接使用类方法替代复杂的send函数调用,提高代码可维护性。
@molanp molanp merged commit 5594f9e into main Jan 15, 2026
2 checks passed
@molanp molanp deleted the feat/iss_17 branch January 15, 2026 13:09
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.

[Feature Request]: 计划任务管理

2 participants