Conversation
- 将 API 类中的实例方法改为静态方法,简化使用 - 优化模型定义,提高代码可读性和维护性 - 新增 common 模型模块,用于定义通用的模型结构 - 调整文件列表和 Docker 相关模型结构,增强数据表达能力
审阅者指南此 PR 将所有 API 类方法重构为静态方法,将 Pydantic 模型定义升级到 v2 兼容性,集中管理共享模型,丰富数据模型中的类型注解和枚举使用,并更新项目要求以支持 Python>=3.10 和 Pydantic>=2.0。 新公共模型及其用法的实体关系图erDiagram
DaemonModel ||--o| CpuMemChart : has
DaemonModel ||--o| ProcessInfo : has
DaemonModel ||--o| InstanceInfo : has
OverviewModel ||--o| CpuMemChart : has
OverviewModel ||--o| InstanceInfo : has
OverviewModel ||--o| ProcessInfo : has
重构后的静态方法 API 类的类图classDiagram
class Instance {
+static search(daemonId, page, page_size, keyword, type, tag)
+static detail(daemonId, uuid)
+static create(daemonId, config)
+static updateConfig(daemonId, uuid, config)
+static delete(daemonId, uuids, deleteFile)
+static start(daemonId, uuid)
+static stop(daemonId, uuid)
+static restart(daemonId, uuid)
+static kill(daemonId, uuid)
+static batchOperation(instances, operation)
+static update(daemonId, uuid)
+static command(daemonId, uuid, command)
+static get_output(daemonId, uuid, size)
+static reinstall(daemonId, uuid, targetUrl, title, description)
}
class File {
+static show(daemonId, uuid, target, page, page_size, file_name)
+static content(daemonId, uuid, target)
+static update(daemonId, uuid, target, text)
+static download(daemonId, uuid, file_name)
+static upload(daemonId, uuid, file, upload_dir)
+static copy(daemonId, uuid, copy_map)
+static copyOne(daemonId, uuid, source, target)
+static move(daemonId, uuid, copy_map)
+static moveOne(daemonId, uuid, source, target)
+static rename(daemonId, uuid, source, new_name)
+static zip(daemonId, uuid, source, targets)
+static unzip(daemonId, uuid, source, target, code)
+static delete(daemonId, uuid, targets)
+static createFile(daemonId, uuid, target)
+static createFloder(daemonId, uuid, target)
}
class Daemon {
+static show()
+static system()
+static add(config)
+static delete(daemonId)
+static link(daemonId)
+static update(daemonId, config)
}
class Image {
+static images(daemonId)
+static containers(daemonId)
+static network(daemonId)
+static add(daemonId, dockerFile, name, tag)
+static progress(daemonId)
}
class User {
+static search(username, page, page_size, role)
+static create(username, password, permission)
+static update(uuid, config)
+static delete(uuids)
}
class Overview {
+static init()
}
更新后的 InstanceConfig 和相关枚举的类图classDiagram
class InstanceConfig {
nickname: str
startCommand: str
stopCommand: str
cwd: str
ie: str
oe: str
createDatetime: int
lastDatetime: int
type: str
tag: list[str]
endTime: int | None
fileCode: str
processType: str
updateCommand: str
actionCommandlist: list[str]
crlf: CRLFType
docker: DockerConfig
enableRcon: bool
rconPassword: str
rconPort: int
rconIp: str
terminalOption: TerminalOption
eventTask: EventTask
pingConfig: PingConfig
runAs: str
}
class CRLFType {
LF
CR
CRLF
}
class Status {
BUSY
STOP
STOPPING
STARTING
RUNNING
}
InstanceConfig --> CRLFType
InstanceConfig --> DockerConfig
InstanceConfig --> TerminalOption
InstanceConfig --> EventTask
InstanceConfig --> PingConfig
新公共模型模块的类图classDiagram
class CpuMemChart {
cpu: float
mem: float
}
class ProcessInfo {
cpu: int
memory: int
cwd: str
}
class InstanceInfo {
running: int
total: int
}
更新后的 FileItem 和 FileType 枚举的类图classDiagram
class FileItem {
name: str
size: int
time: str
mode: int
type: FileType
daemonId: str
uuid: str
target: str
file_name: str
}
class FileType {
FOLDER
FILE
}
FileItem --> FileType
更新后的 UserModel 和 UserPermission 枚举的类图classDiagram
class UserModel {
uuid: str
userName: str
passWord: str
passWordType: int
salt: str
permission: UserPermission
registerTime: str
loginTime: str
apiKey: str
isInit: bool
secret: str
open2FA: bool
instances: list[UserInstancesList]
}
class UserPermission {
BANNED
USER
ADMIN
}
UserModel --> UserPermission
文件级变更
提示和命令与 Sourcery 互动
自定义你的体验访问你的 仪表板 以:
获取帮助Original review guide in EnglishReviewer's GuideThis PR refactors all API class methods to static, upgrades Pydantic model definitions for v2 compatibility, centralizes shared models, enriches type annotations and enum usage in data models, and updates project requirements for Python>=3.10 and Pydantic>=2.0. Entity relationship diagram for new common models and their usageerDiagram
DaemonModel ||--o| CpuMemChart : has
DaemonModel ||--o| ProcessInfo : has
DaemonModel ||--o| InstanceInfo : has
OverviewModel ||--o| CpuMemChart : has
OverviewModel ||--o| InstanceInfo : has
OverviewModel ||--o| ProcessInfo : has
Class diagram for refactored API classes with static methodsclassDiagram
class Instance {
+static search(daemonId, page, page_size, keyword, type, tag)
+static detail(daemonId, uuid)
+static create(daemonId, config)
+static updateConfig(daemonId, uuid, config)
+static delete(daemonId, uuids, deleteFile)
+static start(daemonId, uuid)
+static stop(daemonId, uuid)
+static restart(daemonId, uuid)
+static kill(daemonId, uuid)
+static batchOperation(instances, operation)
+static update(daemonId, uuid)
+static command(daemonId, uuid, command)
+static get_output(daemonId, uuid, size)
+static reinstall(daemonId, uuid, targetUrl, title, description)
}
class File {
+static show(daemonId, uuid, target, page, page_size, file_name)
+static content(daemonId, uuid, target)
+static update(daemonId, uuid, target, text)
+static download(daemonId, uuid, file_name)
+static upload(daemonId, uuid, file, upload_dir)
+static copy(daemonId, uuid, copy_map)
+static copyOne(daemonId, uuid, source, target)
+static move(daemonId, uuid, copy_map)
+static moveOne(daemonId, uuid, source, target)
+static rename(daemonId, uuid, source, new_name)
+static zip(daemonId, uuid, source, targets)
+static unzip(daemonId, uuid, source, target, code)
+static delete(daemonId, uuid, targets)
+static createFile(daemonId, uuid, target)
+static createFloder(daemonId, uuid, target)
}
class Daemon {
+static show()
+static system()
+static add(config)
+static delete(daemonId)
+static link(daemonId)
+static update(daemonId, config)
}
class Image {
+static images(daemonId)
+static containers(daemonId)
+static network(daemonId)
+static add(daemonId, dockerFile, name, tag)
+static progress(daemonId)
}
class User {
+static search(username, page, page_size, role)
+static create(username, password, permission)
+static update(uuid, config)
+static delete(uuids)
}
class Overview {
+static init()
}
Class diagram for updated InstanceConfig and related enumsclassDiagram
class InstanceConfig {
nickname: str
startCommand: str
stopCommand: str
cwd: str
ie: str
oe: str
createDatetime: int
lastDatetime: int
type: str
tag: list[str]
endTime: int | None
fileCode: str
processType: str
updateCommand: str
actionCommandlist: list[str]
crlf: CRLFType
docker: DockerConfig
enableRcon: bool
rconPassword: str
rconPort: int
rconIp: str
terminalOption: TerminalOption
eventTask: EventTask
pingConfig: PingConfig
runAs: str
}
class CRLFType {
LF
CR
CRLF
}
class Status {
BUSY
STOP
STOPPING
STARTING
RUNNING
}
InstanceConfig --> CRLFType
InstanceConfig --> DockerConfig
InstanceConfig --> TerminalOption
InstanceConfig --> EventTask
InstanceConfig --> PingConfig
Class diagram for new common models moduleclassDiagram
class CpuMemChart {
cpu: float
mem: float
}
class ProcessInfo {
cpu: int
memory: int
cwd: str
}
class InstanceInfo {
running: int
total: int
}
Class diagram for updated FileItem and FileType enumclassDiagram
class FileItem {
name: str
size: int
time: str
mode: int
type: FileType
daemonId: str
uuid: str
target: str
file_name: str
}
class FileType {
FOLDER
FILE
}
FileItem --> FileType
Class diagram for updated UserModel and UserPermission enumclassDiagram
class UserModel {
uuid: str
userName: str
passWord: str
passWordType: int
salt: str
permission: UserPermission
registerTime: str
loginTime: str
apiKey: str
isInit: bool
secret: str
open2FA: bool
instances: list[UserInstancesList]
}
class UserPermission {
BANNED
USER
ADMIN
}
UserModel --> UserPermission
File-Level Changes
Tips and commandsInteracting with Sourcery
Customizing Your ExperienceAccess your dashboard to:
Getting Help
|
There was a problem hiding this comment.
你好 - 我已经审阅了你的更改,它们看起来很棒!
AI 代理的提示
请处理此代码审查中的评论:
## 个人评论
### 评论 1
<location> `mcsmapi/models/instance.py:87` </location>
<code_context>
+ """进程类型 (如 docker, local)"""
updateCommand: str = "shutdown -s"
+ """更新命令"""
+ actionCommandlist: list[str] = []
"""实例可执行的操作命令列表"""
- actionCommandList: List[str] = []
</code_context>
<issue_to_address>
命名不一致:'actionCommandlist' 应为 'actionCommandList' 以保持一致性。
请将 'actionCommandlist' 重命名为 'actionCommandList',以保持一致的驼峰命名并避免潜在的混淆或错误。
</issue_to_address>
### 评论 2
<location> `mcsmapi/models/instance.py` </location>
<code_context>
+ def files(self, target: str = "", page: int = 0, page_size: int = 100) -> FileList:
</code_context>
<issue_to_address>
返回类型注解拼写错误:'Filelist' 应为 'FileList'。
请更新文档字符串以使用正确的类名 'FileList' 以保持一致性。
</issue_to_address>
### 评论 3
<location> `mcsmapi/models/file.py:214` </location>
<code_context>
- return File().createFile(self.daemonId, self.uuid, target)
+ return File.createFile(self.daemonId, self.uuid, target)
def createFloder(self, target: str) -> bool:
"""
</code_context>
<issue_to_address>
方法名拼写错误:'createFloder' 应为 'createFolder'。
请将方法重命名为 'createFolder' 以保持一致性。
建议的实现:
```python
def createFolder(self, target: str) -> bool:
"""
"""
from mcsmapi.apis.file import File
return File.createFile(self.daemonId, self.uuid, target)
```
如果你的代码库中其他地方有调用 `createFloder`,你也需要将它们更新为 `createFolder`。
</issue_to_address>
### 评论 4
<location> `mcsmapi/models/instance.py:25` </location>
<code_context>
+ RUNNING = 3
+
+
class TerminalOption(BaseModel):
"""终端选项"""
</code_context>
<issue_to_address>
考虑用 Pydantic 字段描述替换每个字段的文档字符串,以使模型类更简洁。
考虑将每个字段的文档字符串合并到 Pydantic `Field(..., description=…)` 调用中。这将消除数十行重复的 `"""…"""`,并使类更加简洁,同时保留所有元数据:
```python
from enum import IntEnum
from typing import Optional, List
from pydantic import BaseModel, Field
class CRLFType(IntEnum):
"""换行符"""
LF = 0
CR = 1
CRLF = 2
class Status(IntEnum):
"""实例状态"""
BUSY = -1
STOP = 0
STOPPING = 1
STARTING = 2
RUNNING = 3
class InstanceConfig(BaseModel):
nickname: str = Field("New Name", description="实例名称")
startCommand: str = Field("cmd.exe", description="启动命令")
stopCommand: str = Field("^C", description="停止命令")
cwd: str = Field("", description="工作目录")
ie: str = Field("utf8", description="输入编码")
oe: str = Field("utf8", description="输出编码")
createDatetime: int = Field(0, description="创建时间 (Unix 时间戳)")
lastDatetime: int = Field(0, description="最后修改时间 (Unix 时间戳)")
type: str = Field("universal", description="实例类型 (universal, minecraft 等)")
tag: List[str] = Field(default_factory=list, description="实例标签")
endTime: Optional[int] = Field(None, description="实例到期时间")
fileCode: str = Field("utf8", description="文件编码")
processType: str = Field("docker", description="进程类型 (如 docker, local)")
updateCommand: str = Field("shutdown -s", description="更新命令")
actionCommandList: List[str] = Field(default_factory=list, description="实例可执行的操作命令列表")
crlf: CRLFType = Field(CRLFType.CRLF, description="换行符")
docker: DockerConfig = Field(default_factory=DockerConfig, description="Docker 相关配置")
enableRcon: bool = Field(True, description="是否启用 RCON 远程控制")
rconPassword: str = Field("", description="RCON 连接密码")
rconPort: int = Field(2557, description="RCON 端口")
rconIp: str = Field("", description="RCON IP 地址")
# ...and so on for the rest of your fields
```
在 `TerminalOption`、`EventTask`、`PingConfig`、`ProcessInfo` 等中重复相同的模式,并删除独立的三个引号的文档字符串。这将在模式/IDE 提示中保留所有描述,同时大幅减少样板代码。
</issue_to_address>
### 评论 5
<location> `mcsmapi/apis/file.py:8` </location>
<code_context>
class File:
+ @staticmethod
def show(
</code_context>
<issue_to_address>
考虑将静态方法类重构为顶级函数,以简化代码并删除不必要的装饰器和参数。
当没有共享状态时,你实际上不需要一个全是 `@staticmethod` 包装方法的类。将它们提取到顶级函数(或少量模块)中,你可以删除数十个装饰器和未使用的 `self` 参数。
例如,创建一个新文件 `mcsmapi/file_api.py`:
```python
# mcsmapi/file_api.py
from mcsmapi.pool import ApiPool
from mcsmapi.request import send, upload
from mcsmapi.models.file import CommonConfig, FileList
import urllib.parse, os
def show(
daemonId: str,
uuid: str,
target: str = "",
page: int = 0,
page_size: int = 100,
file_name: str = "",
) -> FileList:
result = send(
"PUT",
f"{ApiPool.FILE}/list",
params={"daemonId": daemonId, "uuid": uuid},
data={
"target": target,
"page": page,
"page_size": page_size,
"file_name": file_name,
},
)
return FileList(**result, daemonId=daemonId, uuid=uuid)
def content(daemonId: str, uuid: str, target: str) -> str | bytes:
return send(
"PUT",
f"{ApiPool.FILE}",
params={"daemonId": daemonId, "uuid": uuid},
data={"target": target},
)
async def upload(daemonId: str, uuid: str, file: bytes, upload_dir: str) -> bool:
result = send(
"POST",
f"{ApiPool.FILE}/upload",
params={"daemonId": daemonId, "uuid": uuid, "upload_dir": upload_dir},
)
cfg = CommonConfig(**result)
proto = Request.mcsm_url.split("://")[0]
base_url = urllib.parse.urljoin(f"{proto}://{cfg.addr}", "upload")
final = urllib.parse.urljoin(base_url, cfg.password)
await upload(final, file)
return True
# …etc for update, download, copy, move, delete, etc…
```
然后在你的公共 API 中,你只需:
```python
from .file_api import (
show, content, update, download, upload,
copy, move, copyOne, moveOne,
rename, zip, unzip, delete, createFile, createFolder
)
```
这将删除所有 `@staticmethod` 行,消除方法中从未使用过的 `self`,并使调用站点同样容易(例如 `file_api.show(...)`)。
</issue_to_address>
### 评论 6
<location> `mcsmapi/apis/instance.py:12` </location>
<code_context>
class Instance:
+ @staticmethod
def search(
</code_context>
<issue_to_address>
考虑将静态方法类重构为模块级函数,并使用共享助手来减少重复和样板代码。
以下是将几乎相同的静态方法折叠成普通的模块级函数 + 一个小型助手,并完全删除类的一种方法:
1. 在文件顶部引入一个助手:
```python
def _instance_call(
method: str,
endpoint: str,
params: dict[str, Any] | None = None,
data: Any | None = None,
) -> Any:
return send(method, endpoint, params=params, data=data)
```
2. 将你的静态方法转换为最小函数:
```python
def detail(daemonId: str, uuid: str) -> InstanceDetail:
res = _instance_call("GET", ApiPool.INSTANCE, params={"daemonId": daemonId, "uuid": uuid})
return InstanceDetail(**res)
def create(daemonId: str, config: dict[str, Any]) -> InstanceCreateResult:
res = _instance_call("POST", ApiPool.INSTANCE, params={"daemonId": daemonId}, data=InstanceConfig(**config).dict())
return InstanceCreateResult(**res)
```
3. 将所有“start/stop/restart/kill/command/output”折叠成一个单一的工厂:
```python
def _power_action(
action: Literal["open","stop","restart","kill","command","outputlog"],
daemonId: str,
uuid: str,
**extra,
) -> Any:
path = f"{ApiPool.PROTECTED_INSTANCE}/{action}"
params = {"daemonId": daemonId, "uuid": uuid, **extra}
res = _instance_call("GET", path, params=params)
# most of these return instanceUuid; outputlog returns raw string
return extra.get("command") and res.get("instanceUuid", True) or res
```
使用示例:
```python
def start(daemonId: str, uuid: str) -> str | bool:
return _power_action("open", daemonId, uuid)
def command(daemonId: str, uuid: str, command: str) -> str | bool:
return _power_action("command", daemonId, uuid, command=command)
def get_output(daemonId: str, uuid: str, size: int | str = "") -> str:
return _power_action("outputlog", daemonId, uuid, size=size)
```
这将删除所有 `@staticmethod` 噪音,合并重复的发送调用,并保持完整的功能。
</issue_to_address>帮助我更有用!请点击每个评论上的 👍 或 👎,我将使用反馈来改进您的评论。
Original comment in English
Hey there - I've reviewed your changes and they look great!
Prompt for AI Agents
Please address the comments from this code review:
## Individual Comments
### Comment 1
<location> `mcsmapi/models/instance.py:87` </location>
<code_context>
+ """进程类型 (如 docker, local)"""
updateCommand: str = "shutdown -s"
+ """更新命令"""
+ actionCommandlist: list[str] = []
"""实例可执行的操作命令列表"""
- actionCommandList: List[str] = []
</code_context>
<issue_to_address>
Inconsistent naming: 'actionCommandlist' should be 'actionCommandList' for consistency.
Please rename 'actionCommandlist' to 'actionCommandList' to maintain consistent camelCase naming and avoid potential confusion or bugs.
</issue_to_address>
### Comment 2
<location> `mcsmapi/models/instance.py` </location>
<code_context>
+ def files(self, target: str = "", page: int = 0, page_size: int = 100) -> FileList:
</code_context>
<issue_to_address>
Return type annotation typo: 'Filelist' should be 'FileList'.
Please update the docstring to use the correct class name 'FileList' for consistency.
</issue_to_address>
### Comment 3
<location> `mcsmapi/models/file.py:214` </location>
<code_context>
- return File().createFile(self.daemonId, self.uuid, target)
+ return File.createFile(self.daemonId, self.uuid, target)
def createFloder(self, target: str) -> bool:
"""
</code_context>
<issue_to_address>
Typo in method name: 'createFloder' should be 'createFolder'.
Please rename the method to 'createFolder' for consistency.
Suggested implementation:
```python
def createFolder(self, target: str) -> bool:
"""
"""
from mcsmapi.apis.file import File
return File.createFile(self.daemonId, self.uuid, target)
```
If there are any calls to `createFloder` elsewhere in your codebase, you will need to update those to `createFolder` as well.
</issue_to_address>
### Comment 4
<location> `mcsmapi/models/instance.py:25` </location>
<code_context>
+ RUNNING = 3
+
+
class TerminalOption(BaseModel):
"""终端选项"""
</code_context>
<issue_to_address>
Consider replacing per-field docstrings with Pydantic Field descriptions to make model classes more concise.
Consider collapsing per‐field docstrings into Pydantic `Field(..., description=…)` calls. This will remove dozens of lines of repeated `"""…"""` and make the class far more concise while keeping all metadata:
```python
from enum import IntEnum
from typing import Optional, List
from pydantic import BaseModel, Field
class CRLFType(IntEnum):
"""换行符"""
LF = 0
CR = 1
CRLF = 2
class Status(IntEnum):
"""实例状态"""
BUSY = -1
STOP = 0
STOPPING = 1
STARTING = 2
RUNNING = 3
class InstanceConfig(BaseModel):
nickname: str = Field("New Name", description="实例名称")
startCommand: str = Field("cmd.exe", description="启动命令")
stopCommand: str = Field("^C", description="停止命令")
cwd: str = Field("", description="工作目录")
ie: str = Field("utf8", description="输入编码")
oe: str = Field("utf8", description="输出编码")
createDatetime: int = Field(0, description="创建时间 (Unix 时间戳)")
lastDatetime: int = Field(0, description="最后修改时间 (Unix 时间戳)")
type: str = Field("universal", description="实例类型 (universal, minecraft 等)")
tag: List[str] = Field(default_factory=list, description="实例标签")
endTime: Optional[int] = Field(None, description="实例到期时间")
fileCode: str = Field("utf8", description="文件编码")
processType: str = Field("docker", description="进程类型 (如 docker, local)")
updateCommand: str = Field("shutdown -s", description="更新命令")
actionCommandList: List[str] = Field(default_factory=list, description="实例可执行的操作命令列表")
crlf: CRLFType = Field(CRLFType.CRLF, description="换行符")
docker: DockerConfig = Field(default_factory=DockerConfig, description="Docker 相关配置")
enableRcon: bool = Field(True, description="是否启用 RCON 远程控制")
rconPassword: str = Field("", description="RCON 连接密码")
rconPort: int = Field(2557, description="RCON 端口")
rconIp: str = Field("", description="RCON IP 地址")
# ...and so on for the rest of your fields
```
Repeat the same pattern in `TerminalOption`, `EventTask`, `PingConfig`, `ProcessInfo`, etc., and remove the standalone triple‐quoted docstrings. This keeps all descriptions intact in schema/IDE hints but slashes the boilerplate.
</issue_to_address>
### Comment 5
<location> `mcsmapi/apis/file.py:8` </location>
<code_context>
class File:
+ @staticmethod
def show(
</code_context>
<issue_to_address>
Consider refactoring the class of static methods into top-level functions to simplify the code and remove unnecessary decorators and parameters.
You don’t actually need a class full of `@staticmethod`-wrapped methods when there is no shared state. Pull them out into top‐level functions (or a small handful of modules) and you can delete dozens of decorators and the unused `self` parameter.
For example, create a new file `mcsmapi/file_api.py`:
```python
# mcsmapi/file_api.py
from mcsmapi.pool import ApiPool
from mcsmapi.request import send, upload
from mcsmapi.models.file import CommonConfig, FileList
import urllib.parse, os
def show(
daemonId: str,
uuid: str,
target: str = "",
page: int = 0,
page_size: int = 100,
file_name: str = "",
) -> FileList:
result = send(
"PUT",
f"{ApiPool.FILE}/list",
params={"daemonId": daemonId, "uuid": uuid},
data={
"target": target,
"page": page,
"page_size": page_size,
"file_name": file_name,
},
)
return FileList(**result, daemonId=daemonId, uuid=uuid)
def content(daemonId: str, uuid: str, target: str) -> str | bytes:
return send(
"PUT",
f"{ApiPool.FILE}",
params={"daemonId": daemonId, "uuid": uuid},
data={"target": target},
)
async def upload(daemonId: str, uuid: str, file: bytes, upload_dir: str) -> bool:
result = send(
"POST",
f"{ApiPool.FILE}/upload",
params={"daemonId": daemonId, "uuid": uuid, "upload_dir": upload_dir},
)
cfg = CommonConfig(**result)
proto = Request.mcsm_url.split("://")[0]
base_url = urllib.parse.urljoin(f"{proto}://{cfg.addr}", "upload")
final = urllib.parse.urljoin(base_url, cfg.password)
await upload(final, file)
return True
# …etc for update, download, copy, move, delete, etc…
```
Then in your public API you simply:
```python
from .file_api import (
show, content, update, download, upload,
copy, move, copyOne, moveOne,
rename, zip, unzip, delete, createFile, createFolder
)
```
This removes every `@staticmethod` line, gets rid of `self` on methods that never use it, and makes call‐sites just as easy (e.g. `file_api.show(...)`).
</issue_to_address>
### Comment 6
<location> `mcsmapi/apis/instance.py:12` </location>
<code_context>
class Instance:
+ @staticmethod
def search(
</code_context>
<issue_to_address>
Consider refactoring the class of static methods into module-level functions with shared helpers to reduce duplication and boilerplate.
Here’s one way to collapse almost‐identical static methods into plain module-level functions + a small helper, dropping the class entirely:
1. Introduce a helper at top of the file:
```python
def _instance_call(
method: str,
endpoint: str,
params: dict[str, Any] | None = None,
data: Any | None = None,
) -> Any:
return send(method, endpoint, params=params, data=data)
```
2. Turn your static methods into minimal functions:
```python
def detail(daemonId: str, uuid: str) -> InstanceDetail:
res = _instance_call("GET", ApiPool.INSTANCE, params={"daemonId": daemonId, "uuid": uuid})
return InstanceDetail(**res)
def create(daemonId: str, config: dict[str, Any]) -> InstanceCreateResult:
res = _instance_call("POST", ApiPool.INSTANCE, params={"daemonId": daemonId}, data=InstanceConfig(**config).dict())
return InstanceCreateResult(**res)
```
3. Collapse all “start/stop/restart/kill/command/output” into a single factory:
```python
def _power_action(
action: Literal["open","stop","restart","kill","command","outputlog"],
daemonId: str,
uuid: str,
**extra,
) -> Any:
path = f"{ApiPool.PROTECTED_INSTANCE}/{action}"
params = {"daemonId": daemonId, "uuid": uuid, **extra}
res = _instance_call("GET", path, params=params)
# most of these return instanceUuid; outputlog returns raw string
return extra.get("command") and res.get("instanceUuid", True) or res
```
Usage examples:
```python
def start(daemonId: str, uuid: str) -> str | bool:
return _power_action("open", daemonId, uuid)
def command(daemonId: str, uuid: str, command: str) -> str | bool:
return _power_action("command", daemonId, uuid, command=command)
def get_output(daemonId: str, uuid: str, size: int | str = "") -> str:
return _power_action("outputlog", daemonId, uuid, size=size)
```
This removes all the `@staticmethod` noise, collapses duplicated send-calls, and keeps full functionality.
</issue_to_address>Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.
| @@ -10,8 +10,8 @@ | |||
|
|
|||
|
|
|||
| class Instance: | |||
There was a problem hiding this comment.
issue (complexity): 考虑将静态方法类重构为模块级函数,并使用共享助手来减少重复和样板代码。
以下是将几乎相同的静态方法折叠成普通的模块级函数 + 一个小型助手,并完全删除类的一种方法:
- 在文件顶部引入一个助手:
def _instance_call(
method: str,
endpoint: str,
params: dict[str, Any] | None = None,
data: Any | None = None,
) -> Any:
return send(method, endpoint, params=params, data=data)- 将你的静态方法转换为最小函数:
def detail(daemonId: str, uuid: str) -> InstanceDetail:
res = _instance_call("GET", ApiPool.INSTANCE, params={"daemonId": daemonId, "uuid": uuid})
return InstanceDetail(**res)
def create(daemonId: str, config: dict[str, Any]) -> InstanceCreateResult:
res = _instance_call("POST", ApiPool.INSTANCE, params={"daemonId": daemonId}, data=InstanceConfig(**config).dict())
return InstanceCreateResult(**res)- 将所有“start/stop/restart/kill/command/output”折叠成一个单一的工厂:
def _power_action(
action: Literal["open","stop","restart","kill","command","outputlog"],
daemonId: str,
uuid: str,
**extra,
) -> Any:
path = f"{ApiPool.PROTECTED_INSTANCE}/{action}"
params = {"daemonId": daemonId, "uuid": uuid, **extra}
res = _instance_call("GET", path, params=params)
# most of these return instanceUuid; outputlog returns raw string
return extra.get("command") and res.get("instanceUuid", True) or res使用示例:
def start(daemonId: str, uuid: str) -> str | bool:
return _power_action("open", daemonId, uuid)
def command(daemonId: str, uuid: str, command: str) -> str | bool:
return _power_action("command", daemonId, uuid, command=command)
def get_output(daemonId: str, uuid: str, size: int | str = "") -> str:
return _power_action("outputlog", daemonId, uuid, size=size)这将删除所有 @staticmethod 噪音,合并重复的发送调用,并保持完整的功能。
Original comment in English
issue (complexity): Consider refactoring the class of static methods into module-level functions with shared helpers to reduce duplication and boilerplate.
Here’s one way to collapse almost‐identical static methods into plain module-level functions + a small helper, dropping the class entirely:
- Introduce a helper at top of the file:
def _instance_call(
method: str,
endpoint: str,
params: dict[str, Any] | None = None,
data: Any | None = None,
) -> Any:
return send(method, endpoint, params=params, data=data)- Turn your static methods into minimal functions:
def detail(daemonId: str, uuid: str) -> InstanceDetail:
res = _instance_call("GET", ApiPool.INSTANCE, params={"daemonId": daemonId, "uuid": uuid})
return InstanceDetail(**res)
def create(daemonId: str, config: dict[str, Any]) -> InstanceCreateResult:
res = _instance_call("POST", ApiPool.INSTANCE, params={"daemonId": daemonId}, data=InstanceConfig(**config).dict())
return InstanceCreateResult(**res)- Collapse all “start/stop/restart/kill/command/output” into a single factory:
def _power_action(
action: Literal["open","stop","restart","kill","command","outputlog"],
daemonId: str,
uuid: str,
**extra,
) -> Any:
path = f"{ApiPool.PROTECTED_INSTANCE}/{action}"
params = {"daemonId": daemonId, "uuid": uuid, **extra}
res = _instance_call("GET", path, params=params)
# most of these return instanceUuid; outputlog returns raw string
return extra.get("command") and res.get("instanceUuid", True) or resUsage examples:
def start(daemonId: str, uuid: str) -> str | bool:
return _power_action("open", daemonId, uuid)
def command(daemonId: str, uuid: str, command: str) -> str | bool:
return _power_action("command", daemonId, uuid, command=command)
def get_output(daemonId: str, uuid: str, size: int | str = "") -> str:
return _power_action("outputlog", daemonId, uuid, size=size)This removes all the @staticmethod noise, collapses duplicated send-calls, and keeps full functionality.
- 将 API 类中的实例方法改为静态方法,简化使用 - 优化模型定义,提高代码可读性和维护性 - 新增 common 模型模块,用于定义通用的模型结构 - 调整文件列表和 Docker 相关模型结构,增强数据表达能力
Sourcery 总结
重构 API 类以使用静态方法,并通过整合通用模式、升级到 Pydantic v2 规范、引入枚举类型用于关键字段以及扩展模型结构来现代化所有 Pydantic 模型
新功能:
改进:
构建:
Original summary in English
Summary by Sourcery
Refactor API classes to use static methods and modernize all Pydantic models by consolidating common schemas, upgrading to Pydantic v2 conventions, introducing enums for key fields, and expanding model structures
New Features:
Enhancements:
Build: