data-ops-cli 0.3.4__tar.gz → 0.3.5__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (35) hide show
  1. {data_ops_cli-0.3.4 → data_ops_cli-0.3.5}/PKG-INFO +1 -1
  2. {data_ops_cli-0.3.4 → data_ops_cli-0.3.5}/src/data_ops_cli.egg-info/PKG-INFO +1 -1
  3. {data_ops_cli-0.3.4 → data_ops_cli-0.3.5}/src/dataops_cli/__init__.py +1 -1
  4. {data_ops_cli-0.3.4 → data_ops_cli-0.3.5}/src/dataops_cli/cli/alarm.py +251 -22
  5. {data_ops_cli-0.3.4 → data_ops_cli-0.3.5}/src/dataops_cli/cli/api.py +1 -1
  6. {data_ops_cli-0.3.4 → data_ops_cli-0.3.5}/src/dataops_cli/cli/auth.py +4 -2
  7. {data_ops_cli-0.3.4 → data_ops_cli-0.3.5}/src/dataops_cli/cli/data_table.py +1 -1
  8. {data_ops_cli-0.3.4 → data_ops_cli-0.3.5}/src/dataops_cli/cli/dataset.py +3 -3
  9. {data_ops_cli-0.3.4 → data_ops_cli-0.3.5}/src/dataops_cli/cli/datasource.py +1 -4
  10. {data_ops_cli-0.3.4 → data_ops_cli-0.3.5}/src/dataops_cli/cli/dict_.py +4 -4
  11. {data_ops_cli-0.3.4 → data_ops_cli-0.3.5}/src/dataops_cli/cli/metrics.py +3 -3
  12. {data_ops_cli-0.3.4 → data_ops_cli-0.3.5}/src/dataops_cli/cli/report.py +3 -3
  13. {data_ops_cli-0.3.4 → data_ops_cli-0.3.5}/src/dataops_cli/cli/skill.py +26 -48
  14. {data_ops_cli-0.3.4 → data_ops_cli-0.3.5}/src/dataops_cli/cli/table.py +4 -4
  15. {data_ops_cli-0.3.4 → data_ops_cli-0.3.5}/src/dataops_cli/cli/widget.py +1 -1
  16. {data_ops_cli-0.3.4 → data_ops_cli-0.3.5}/src/dataops_cli/cli/workflow.py +1 -1
  17. {data_ops_cli-0.3.4 → data_ops_cli-0.3.5}/pyproject.toml +0 -0
  18. {data_ops_cli-0.3.4 → data_ops_cli-0.3.5}/setup.cfg +0 -0
  19. {data_ops_cli-0.3.4 → data_ops_cli-0.3.5}/src/data_ops_cli.egg-info/SOURCES.txt +0 -0
  20. {data_ops_cli-0.3.4 → data_ops_cli-0.3.5}/src/data_ops_cli.egg-info/dependency_links.txt +0 -0
  21. {data_ops_cli-0.3.4 → data_ops_cli-0.3.5}/src/data_ops_cli.egg-info/entry_points.txt +0 -0
  22. {data_ops_cli-0.3.4 → data_ops_cli-0.3.5}/src/data_ops_cli.egg-info/requires.txt +0 -0
  23. {data_ops_cli-0.3.4 → data_ops_cli-0.3.5}/src/data_ops_cli.egg-info/top_level.txt +0 -0
  24. {data_ops_cli-0.3.4 → data_ops_cli-0.3.5}/src/dataops_cli/_compat.py +0 -0
  25. {data_ops_cli-0.3.4 → data_ops_cli-0.3.5}/src/dataops_cli/cli/__init__.py +0 -0
  26. {data_ops_cli-0.3.4 → data_ops_cli-0.3.5}/src/dataops_cli/cli/factory.py +0 -0
  27. {data_ops_cli-0.3.4 → data_ops_cli-0.3.5}/src/dataops_cli/cli/hazard.py +0 -0
  28. {data_ops_cli-0.3.4 → data_ops_cli-0.3.5}/src/dataops_cli/cli/ref.py +0 -0
  29. {data_ops_cli-0.3.4 → data_ops_cli-0.3.5}/src/dataops_cli/cli/utils.py +0 -0
  30. {data_ops_cli-0.3.4 → data_ops_cli-0.3.5}/src/dataops_cli/exceptions.py +0 -0
  31. {data_ops_cli-0.3.4 → data_ops_cli-0.3.5}/src/dataops_cli/runner.py +0 -0
  32. {data_ops_cli-0.3.4 → data_ops_cli-0.3.5}/src/dataops_cli/schems.py +0 -0
  33. {data_ops_cli-0.3.4 → data_ops_cli-0.3.5}/src/dataops_cli/sdk.py +0 -0
  34. {data_ops_cli-0.3.4 → data_ops_cli-0.3.5}/src/dataops_cli/session.py +0 -0
  35. {data_ops_cli-0.3.4 → data_ops_cli-0.3.5}/src/dataops_cli/utils.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: data-ops-cli
3
- Version: 0.3.4
3
+ Version: 0.3.5
4
4
  Summary: Command-line wrapper around dataops_sdk for the DataOps platform.
5
5
  Requires-Python: >=3.11
6
6
  Requires-Dist: dataops-sdk[runner]>=0.3.4
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: data-ops-cli
3
- Version: 0.3.4
3
+ Version: 0.3.5
4
4
  Summary: Command-line wrapper around dataops_sdk for the DataOps platform.
5
5
  Requires-Python: >=3.11
6
6
  Requires-Dist: dataops-sdk[runner]>=0.3.4
@@ -14,4 +14,4 @@ groups command modules under :mod:`dataops_cli.cli` and re-exports the package
14
14
  removed in ``dataops_cli`` 1.0.
15
15
  """
16
16
 
17
- __version__ = "0.3.4"
17
+ __version__ = "0.3.5"
@@ -11,7 +11,6 @@ from typing import Annotated, Any
11
11
 
12
12
  import typer
13
13
  from dataops_sdk.exceptions import DataOpsError
14
- from dataops_sdk.schemas.query import SqlQueryParam
15
14
  from dataops_sdk.services.alarm import (
16
15
  service_count_alarm_action,
17
16
  service_count_alarm_rule_matches,
@@ -19,10 +18,18 @@ from dataops_sdk.services.alarm import (
19
18
  service_count_alarm_specs,
20
19
  service_find_alarm_table_data,
21
20
  service_find_meta_by_codes,
21
+ service_get_alarm_action_detail,
22
+ service_get_alarm_builtin_function_detail,
23
+ service_get_alarm_preprocess_detail,
24
+ service_get_alarm_rule_detail,
22
25
  service_get_alarm_rule_enums,
26
+ service_get_alarm_rule_type_detail,
27
+ service_get_alarm_spec_detail,
23
28
  service_get_alarm_table_columns,
24
29
  service_get_rel_table_columns,
25
30
  service_list_alarm_action,
31
+ service_list_alarm_builtin_functions,
32
+ service_list_alarm_preprocess,
26
33
  service_list_alarm_rule_matches,
27
34
  service_list_alarm_rules,
28
35
  service_list_alarm_specs,
@@ -39,13 +46,21 @@ from dataops_cli.cli.utils import print_list
39
46
 
40
47
  alarm_typer = typer.Typer(name="alarm", help="告警规则配置", no_args_is_help=True)
41
48
  alarm_rule_typer = typer.Typer(name="rule", help="告警规则命令", no_args_is_help=True)
49
+ alarm_rule_type_typer = typer.Typer(name="type", help="告警规则类型命令", no_args_is_help=True)
42
50
  alarm_spec_typer = typer.Typer(name="spec", help="告警专业命令", no_args_is_help=True)
43
51
  alarm_action_typer = typer.Typer(name="action", help="告警动作命令", no_args_is_help=True)
52
+ alarm_preprocess_typer = typer.Typer(name="preprocess", help="预处理脚本命令", no_args_is_help=True)
53
+ alarm_builtin_function_typer = typer.Typer(
54
+ name="builtin-function", help="内置函数命令", no_args_is_help=True
55
+ )
44
56
  rule_match_typer = typer.Typer(name="match", help="规则匹配命令", no_args_is_help=True)
45
57
  alarm_typer.add_typer(alarm_rule_typer, no_args_is_help=True)
46
58
  alarm_typer.add_typer(alarm_spec_typer, no_args_is_help=True)
59
+ alarm_rule_typer.add_typer(alarm_rule_type_typer, no_args_is_help=True)
47
60
  alarm_rule_typer.add_typer(rule_match_typer, no_args_is_help=True)
48
61
  alarm_typer.add_typer(alarm_action_typer, no_args_is_help=True)
62
+ alarm_typer.add_typer(alarm_preprocess_typer, no_args_is_help=True)
63
+ alarm_typer.add_typer(alarm_builtin_function_typer, no_args_is_help=True)
49
64
 
50
65
 
51
66
  def _safe_str(value: Any) -> str:
@@ -87,6 +102,155 @@ def _print_column_list(data: Any) -> None:
87
102
  print(to_json(columns).decode("utf-8"))
88
103
 
89
104
 
105
+ def _print_alarm_detail(detail: Any, title: str, simplify: bool = False) -> None:
106
+ """渲染告警详情的主体、data 和参数。"""
107
+ console = Console(no_color=True)
108
+ meta = detail.meta
109
+ basic_table = Table("字段", "值", title=title, show_header=False)
110
+ for field in ("code", "title", "type", "remark", "createUser", "lastModifyTime"):
111
+ value = getattr(meta, field, None)
112
+ if value is not None:
113
+ basic_table.add_row(field, _safe_str(value))
114
+ console.print(basic_table)
115
+
116
+ data = meta.data or {}
117
+ if hasattr(data, "model_dump"):
118
+ data = data.model_dump(mode="json")
119
+ if isinstance(data, dict):
120
+ data_table = Table("data 字段", "值", title="详情数据", show_header=False)
121
+ for key, value in data.items():
122
+ if simplify and key.lower() in {"script", "scriptcontent", "script_content"}:
123
+ continue
124
+ data_table.add_row(str(key), _safe_str(value))
125
+ if data_table.row_count:
126
+ console.print(data_table)
127
+
128
+ if detail.params:
129
+ params_table = Table("参数", "值", title="Meta 参数", show_header=False)
130
+ for key, value in detail.params.items():
131
+ params_table.add_row(str(key), _safe_str(value))
132
+ console.print(params_table)
133
+
134
+
135
+ def _handle_alarm_detail(detail_service, code: str, title: str, simplify: bool) -> None:
136
+ """统一处理详情 service 的错误和终端输出。"""
137
+ try:
138
+ detail = detail_service(code)
139
+ except DataOpsError as e:
140
+ typer.echo(f"错误: {e.message}")
141
+ raise typer.Exit(code=1) from None
142
+ _print_alarm_detail(detail, title, simplify)
143
+
144
+
145
+ @alarm_preprocess_typer.command("list", help="查询预处理脚本")
146
+ def list_alarm_preprocess(
147
+ spec_type: Annotated[
148
+ list[str] | None, typer.Option("--spec-type", help="关联专业编码,可重复传入")
149
+ ] = None,
150
+ enabled: Annotated[
151
+ list[str] | None, typer.Option("--enabled", help="启用状态值 1/0,可重复传入")
152
+ ] = None,
153
+ page_num: Annotated[int, typer.Option("-n", "--page-num", "--page", help="页码")] = 0,
154
+ page_size: Annotated[int, typer.Option("-s", "--page-size", "--size", help="每页大小")] = 20,
155
+ query: Annotated[str | None, typer.Option("-q", "--query", help="脚本名称关键词")] = None,
156
+ ) -> None:
157
+ """查询预处理脚本列表。"""
158
+ try:
159
+ rows = service_list_alarm_preprocess(
160
+ page_num,
161
+ page_size,
162
+ query,
163
+ spec_type or [],
164
+ enabled or [],
165
+ )
166
+ except DataOpsError as e:
167
+ typer.echo(f"错误: {e.message}")
168
+ raise typer.Exit(code=1) from None
169
+
170
+ if not rows:
171
+ print("未查询到预处理脚本")
172
+ return
173
+ print_list(
174
+ ["脚本编码", "脚本名称", "关联专业", "脚本说明", "启用状态", "创建人", "创建时间"],
175
+ [
176
+ [
177
+ row.CODE,
178
+ row.TITLE,
179
+ row.N_SPEC_TYPE,
180
+ row.DESCRIPTION,
181
+ row.IS_ENABLED,
182
+ row.CREATE_USER,
183
+ row.CREATE_TIME,
184
+ ]
185
+ for row in rows
186
+ ],
187
+ )
188
+
189
+
190
+ @alarm_preprocess_typer.command("detail", no_args_is_help=True)
191
+ def get_alarm_preprocess_detail(
192
+ code: Annotated[str, typer.Argument(help="预处理脚本编码")],
193
+ simplify: Annotated[bool, typer.Option("-s", "--simplify", help="隐藏脚本正文")] = False,
194
+ ) -> None:
195
+ """按编码查询预处理脚本详情。"""
196
+ _handle_alarm_detail(
197
+ service_get_alarm_preprocess_detail,
198
+ code,
199
+ "预处理脚本详情",
200
+ simplify,
201
+ )
202
+
203
+
204
+ @alarm_builtin_function_typer.command("list", help="查询内置函数")
205
+ def list_alarm_builtin_functions(
206
+ enabled: Annotated[
207
+ list[str] | None, typer.Option("--enabled", help="启用状态值 1/0,可重复传入")
208
+ ] = None,
209
+ page_num: Annotated[int, typer.Option("-n", "--page-num", "--page", help="页码")] = 0,
210
+ page_size: Annotated[int, typer.Option("-s", "--page-size", "--size", help="每页大小")] = 20,
211
+ query: Annotated[str | None, typer.Option("-q", "--query", help="函数名称关键词")] = None,
212
+ ) -> None:
213
+ """查询内置函数列表。"""
214
+ try:
215
+ rows = service_list_alarm_builtin_functions(page_num, page_size, query, enabled or [])
216
+ except DataOpsError as e:
217
+ typer.echo(f"错误: {e.message}")
218
+ raise typer.Exit(code=1) from None
219
+
220
+ if not rows:
221
+ print("未查询到内置函数")
222
+ return
223
+ print_list(
224
+ ["函数编码", "函数名称", "类全路径", "备注", "启用状态", "创建人", "创建时间"],
225
+ [
226
+ [
227
+ row.CODE,
228
+ row.TITLE,
229
+ row.CLAZZ,
230
+ row.REMARK,
231
+ row.IS_ENABLED,
232
+ row.CREATE_USER,
233
+ row.CREATE_TIME,
234
+ ]
235
+ for row in rows
236
+ ],
237
+ )
238
+
239
+
240
+ @alarm_builtin_function_typer.command("detail", no_args_is_help=True)
241
+ def get_alarm_builtin_function_detail(
242
+ code: Annotated[str, typer.Argument(help="内置函数编码")],
243
+ simplify: Annotated[bool, typer.Option("-s", "--simplify", help="隐藏函数脚本")] = False,
244
+ ) -> None:
245
+ """按编码查询内置函数详情。"""
246
+ _handle_alarm_detail(
247
+ service_get_alarm_builtin_function_detail,
248
+ code,
249
+ "内置函数详情",
250
+ simplify,
251
+ )
252
+
253
+
90
254
  @rule_match_typer.command("count", help="查询告警匹配规则数量")
91
255
  def count_alarm_rules_match(
92
256
  spec: Annotated[list[str], typer.Option(help="专业值", default_factory=list)],
@@ -116,8 +280,8 @@ def count_alarm_rules_match(
116
280
  @rule_match_typer.command("list", help="查询告警匹配规则")
117
281
  def list_alarm_rules_match(
118
282
  spec: Annotated[list[str], typer.Option(help="专业值", default_factory=list)],
119
- page_num: Annotated[int, typer.Option("-n", "--page-num", help="页码")] = 0,
120
- page_size: Annotated[int, typer.Option("-s", "--page-size", help="每页大小")] = 20,
283
+ page_num: Annotated[int, typer.Option("-n", "--page-num", "--page", help="页码")] = 0,
284
+ page_size: Annotated[int, typer.Option("-s", "--page-size", "--size", help="每页大小")] = 20,
121
285
  query: Annotated[str | None, typer.Option("-q", "--query", help="搜索关键字")] = None,
122
286
  enabled: Annotated[bool | None, typer.Option(help="启用状态")] = None,
123
287
  ):
@@ -169,10 +333,53 @@ def list_alarm_rules_match(
169
333
  )
170
334
 
171
335
 
336
+ @alarm_rule_typer.command("list", help="查询告警匹配规则")
337
+ def list_alarm_rules(
338
+ spec: Annotated[list[str], typer.Option(help="专业值", default_factory=list)],
339
+ page_num: Annotated[int, typer.Option("-n", "--page-num", "--page", help="页码")] = 0,
340
+ page_size: Annotated[int, typer.Option("-s", "--page-size", "--size", help="每页大小")] = 20,
341
+ query: Annotated[str | None, typer.Option("-q", "--query", help="搜索关键字")] = None,
342
+ enabled: Annotated[bool | None, typer.Option(help="启用状态")] = None,
343
+ ) -> None:
344
+ """查询告警匹配规则列表。
345
+
346
+ 这是前端 ``pages/alarm/rule`` 对应的 canonical 命令;旧的
347
+ ``alarm rule match list`` 仍保留作为兼容入口。
348
+ """
349
+ list_alarm_rules_match(spec, page_num, page_size, query, enabled)
350
+
351
+
352
+ @alarm_rule_typer.command("detail", no_args_is_help=True)
353
+ def get_alarm_rule_detail(
354
+ code: Annotated[str, typer.Argument(help="告警匹配规则编码")],
355
+ simplify: Annotated[bool, typer.Option("-s", "--simplify", help="简化详情输出")] = False,
356
+ ) -> None:
357
+ """按编码查询告警匹配规则基础详情。"""
358
+ _handle_alarm_detail(service_get_alarm_rule_detail, code, "告警匹配规则详情", simplify)
359
+
360
+
361
+ @alarm_rule_typer.command("count", help="兼容查询告警规则类型数量")
362
+ def count_alarm_rules_compat(
363
+ query: Annotated[str | None, typer.Option("-q", "--query", help="搜索关键字")] = None,
364
+ enabled: Annotated[bool | None, typer.Option(help="启用状态")] = None,
365
+ ) -> None:
366
+ """兼容保留的原规则类型数量命令。
367
+
368
+ 规则类型的 canonical 列表命令是 ``alarm rule type list``;匹配规则数量
369
+ 仍使用 ``alarm rule match count``。
370
+ """
371
+ try:
372
+ total = service_count_alarm_rules(query, enabled)
373
+ except DataOpsError as e:
374
+ typer.echo(f"错误: {e.message}")
375
+ raise typer.Exit(code=1) from None
376
+ print(total)
377
+
378
+
172
379
  @alarm_spec_typer.command("list", help="查询告警专业")
173
380
  def list_alarm_specs(
174
- page_num: Annotated[int, typer.Option("-n", "--page-num", help="页码")] = 0,
175
- page_size: Annotated[int, typer.Option("-s", "--page-size", help="每页大小")] = 20,
381
+ page_num: Annotated[int, typer.Option("-n", "--page-num", "--page", help="页码")] = 0,
382
+ page_size: Annotated[int, typer.Option("-s", "--page-size", "--size", help="每页大小")] = 20,
176
383
  query: Annotated[str | None, typer.Option("-q", "--query", help="搜索关键字")] = None,
177
384
  active: Annotated[bool | None, typer.Option(help="启用状态")] = None,
178
385
  ):
@@ -189,12 +396,7 @@ def list_alarm_specs(
189
396
  Examples:
190
397
  >>> data-ops-cli alarm spec list -q "网元"
191
398
  """
192
- query_param = SqlQueryParam()
193
- if active is not None:
194
- query_param.varMap["isEnabled"] = "1" if active else "0"
195
- if query:
196
- query_param.add_like("title", query, "mrl")
197
- group_nodes = service_list_alarm_specs(page_num, page_size, query_param)
399
+ group_nodes = service_list_alarm_specs(page_num, page_size, query, active)
198
400
 
199
401
  print_list(
200
402
  ["专业名称", "值", "行业", "启用状态", "创建人", "更新时间"],
@@ -212,6 +414,15 @@ def list_alarm_specs(
212
414
  )
213
415
 
214
416
 
417
+ @alarm_spec_typer.command("detail", no_args_is_help=True)
418
+ def get_alarm_spec_detail(
419
+ code: Annotated[str, typer.Argument(help="告警专业编码")],
420
+ simplify: Annotated[bool, typer.Option("-s", "--simplify", help="简化详情输出")] = False,
421
+ ) -> None:
422
+ """按编码查询告警专业详情。"""
423
+ _handle_alarm_detail(service_get_alarm_spec_detail, code, "告警专业详情", simplify)
424
+
425
+
215
426
  @alarm_spec_typer.command("count", help="查询告警专业数量")
216
427
  def count_alarm_specs(
217
428
  query: Annotated[str | None, typer.Option("-q", "--query", help="搜索关键字")] = None,
@@ -230,14 +441,14 @@ def count_alarm_specs(
230
441
  print(total)
231
442
 
232
443
 
233
- @alarm_rule_typer.command("list", help="查询告警规则")
234
- def list_alarm_rules(
235
- page_num: Annotated[int, typer.Option("-n", "--page-num", help="页码")] = 0,
236
- page_size: Annotated[int, typer.Option("-s", "--page-size", help="每页大小")] = 20,
444
+ @alarm_rule_type_typer.command("list", help="查询告警规则类型")
445
+ def list_alarm_rule_types(
446
+ page_num: Annotated[int, typer.Option("-n", "--page-num", "--page", help="页码")] = 0,
447
+ page_size: Annotated[int, typer.Option("-s", "--page-size", "--size", help="每页大小")] = 20,
237
448
  query: Annotated[str | None, typer.Option("-q", "--query", help="搜索关键字")] = None,
238
449
  enabled: Annotated[bool | None, typer.Option(help="启用状态")] = None,
239
450
  ):
240
- """查询告警规则列表。
451
+ """查询告警规则类型列表。
241
452
 
242
453
  按关键字与启用状态过滤告警规则,并以平面表格输出名称、值与启用状态。
243
454
 
@@ -248,7 +459,7 @@ def list_alarm_rules(
248
459
  enabled: 可选启用状态过滤。
249
460
 
250
461
  Examples:
251
- >>> data-ops-cli alarm rule list -q "电压"
462
+ >>> data-ops-cli alarm rule type list -q "电压"
252
463
  """
253
464
  group_nodes = service_list_alarm_rules(page_num, page_size, query, enabled)
254
465
 
@@ -267,8 +478,17 @@ def list_alarm_rules(
267
478
  )
268
479
 
269
480
 
270
- @alarm_spec_typer.command("count", help="查询告警规则数量")
271
- def count_alarm_specs(
481
+ @alarm_rule_type_typer.command("detail", no_args_is_help=True)
482
+ def get_alarm_rule_type_detail(
483
+ code: Annotated[str, typer.Argument(help="告警规则类型编码")],
484
+ simplify: Annotated[bool, typer.Option("-s", "--simplify", help="简化详情输出")] = False,
485
+ ) -> None:
486
+ """按编码查询告警规则类型详情。"""
487
+ _handle_alarm_detail(service_get_alarm_rule_type_detail, code, "告警规则类型详情", simplify)
488
+
489
+
490
+ @alarm_rule_type_typer.command("count", help="查询告警规则类型数量")
491
+ def count_alarm_rule_types(
272
492
  query: Annotated[str | None, typer.Option("-q", "--query", help="搜索关键字")] = None,
273
493
  enabled: Annotated[bool | None, typer.Option(help="启用状态")] = None,
274
494
  ):
@@ -279,7 +499,7 @@ def count_alarm_specs(
279
499
  enabled: 可选启用状态过滤。
280
500
 
281
501
  Examples:
282
- >>> data-ops-cli alarm rule count
502
+ >>> data-ops-cli alarm rule type count
283
503
  """
284
504
  total = service_count_alarm_rules(query, enabled)
285
505
  print(total)
@@ -288,8 +508,8 @@ def count_alarm_specs(
288
508
  @alarm_action_typer.command("list", help="查询告警动作")
289
509
  def list_alarm_actions(
290
510
  rule: Annotated[list[str], typer.Option(help="专业值", default_factory=list)],
291
- page_num: Annotated[int, typer.Option("-n", "--page-num", help="页码")] = 0,
292
- page_size: Annotated[int, typer.Option("-s", "--page-size", help="每页大小")] = 20,
511
+ page_num: Annotated[int, typer.Option("-n", "--page-num", "--page", help="页码")] = 0,
512
+ page_size: Annotated[int, typer.Option("-s", "--page-size", "--size", help="每页大小")] = 20,
293
513
  query: Annotated[str | None, typer.Option("-q", "--query", help="搜索关键字")] = None,
294
514
  enabled: Annotated[bool | None, typer.Option(help="启用状态")] = None,
295
515
  ):
@@ -339,6 +559,15 @@ def list_alarm_actions(
339
559
  )
340
560
 
341
561
 
562
+ @alarm_action_typer.command("detail", no_args_is_help=True)
563
+ def get_alarm_action_detail(
564
+ code: Annotated[str, typer.Argument(help="告警动作编码")],
565
+ simplify: Annotated[bool, typer.Option("-s", "--simplify", help="简化详情输出")] = False,
566
+ ) -> None:
567
+ """按编码查询告警处置动作详情。"""
568
+ _handle_alarm_detail(service_get_alarm_action_detail, code, "告警处置动作详情", simplify)
569
+
570
+
342
571
  @alarm_action_typer.command("count", help="查询告警动作数量")
343
572
  def count_alarm_actions(
344
573
  rule: Annotated[list[str], typer.Option(help="专业值", default_factory=list)],
@@ -90,7 +90,7 @@ def list_apis(
90
90
 
91
91
  print_list(
92
92
  ["code", "title", "remark"],
93
- [[node.CODE, node.TITLE, _first_line(node.REMARK or "")] for node in group_nodes],
93
+ [[node.code, node.title, _first_line(node.remark or "")] for node in group_nodes],
94
94
  )
95
95
 
96
96
 
@@ -128,7 +128,9 @@ def logout() -> None:
128
128
 
129
129
 
130
130
  @application_typer.command("list")
131
- def application_list(query: Annotated[str | None, typer.Argument(help="关键字")] = None) -> None:
131
+ def application_list(
132
+ query: Annotated[str | None, typer.Option("-q", "--query", help="关键字")] = None,
133
+ ) -> None:
132
134
  """列出所有可用应用。
133
135
 
134
136
  显示当前用户可访问的所有应用列表,支持通过关键字过滤。
@@ -142,7 +144,7 @@ def application_list(query: Annotated[str | None, typer.Argument(help="关键字
142
144
  >>> data-ops-cli auth application list
143
145
 
144
146
  通过关键字过滤应用
145
- >>> data-ops-cli auth application list myapp
147
+ >>> data-ops-cli auth application list -q myapp
146
148
  """
147
149
  try:
148
150
  applications = service_list_applications(query)
@@ -69,7 +69,7 @@ def list_datatable(
69
69
 
70
70
  print_list(
71
71
  ["code", "title", "remark"],
72
- [[column.CODE, column.TITLE, column.REMARK] for column in group_nodes],
72
+ [[column.code, column.title, column.remark] for column in group_nodes],
73
73
  )
74
74
 
75
75
 
@@ -26,7 +26,7 @@ dataset_typer = typer.Typer(name="dataset", help="Manage dataset.", no_args_is_h
26
26
 
27
27
  @dataset_typer.command("list")
28
28
  def list_dataset(
29
- query: Annotated[str | None, typer.Argument(help="名称关键字")] = None,
29
+ query: Annotated[str | None, typer.Option("-q", "--query", help="名称关键字")] = None,
30
30
  ) -> None:
31
31
  """列出所有数据集。
32
32
 
@@ -40,7 +40,7 @@ def list_dataset(
40
40
  >>> data-ops-cli dataset list
41
41
 
42
42
  # 按名称关键字过滤
43
- >>> data-ops-cli dataset list "HHI.*"
43
+ >>> data-ops-cli dataset list -q "HHI.*"
44
44
  """
45
45
  try:
46
46
  group_nodes = service_list_datasets()
@@ -53,7 +53,7 @@ def list_dataset(
53
53
 
54
54
  print_list(
55
55
  ["code", "name", "alias", "remark"],
56
- [[column.CODE, column.NAME, column.TITLE, column.REMARK] for column in group_nodes],
56
+ [[column.code, column.name, column.title, column.remark] for column in group_nodes],
57
57
  )
58
58
 
59
59
 
@@ -100,10 +100,7 @@ def list_datasource(
100
100
 
101
101
  print_list(
102
102
  ["name", "alias", "type", "remark"],
103
- [
104
- [column.NAME, column.TITLE, column.SUB_TYPE, column.REMARK or ""]
105
- for column in group_nodes
106
- ],
103
+ [[column.code, column.name, column.title, column.remark or ""] for column in group_nodes],
107
104
  )
108
105
 
109
106
 
@@ -22,7 +22,7 @@ dict_typer = typer.Typer(name="dict", help="Manage dict.", no_args_is_help=True)
22
22
  @dict_typer.command("list")
23
23
  def list_dict(
24
24
  datasource: Annotated[str, typer.Argument(help="数据源")],
25
- query: Annotated[str | None, typer.Argument(help="字典名称关键字")] = None,
25
+ query: Annotated[str | None, typer.Option("-q", "--query", help="字典名称关键字")] = None,
26
26
  ) -> None:
27
27
  """列出数据源中的字典列表。
28
28
 
@@ -37,10 +37,10 @@ def list_dict(
37
37
  >>> data-ops-cli dict list <datasource>
38
38
 
39
39
  # 列出数据源中名称包含 "user" 的字典
40
- >>> data-ops-cli dict list <datasource> user
40
+ >>> data-ops-cli dict list <datasource> -q user
41
41
 
42
42
  # 使用正则过滤字典名
43
- >>> data-ops-cli dict list <datasource> "^user_.*"
43
+ >>> data-ops-cli dict list <datasource> -q "^user_.*"
44
44
  """
45
45
  try:
46
46
  group_nodes = service_list_dicts(datasource)
@@ -57,7 +57,7 @@ def list_dict(
57
57
 
58
58
  print_list(
59
59
  ["code", "name", "alias"],
60
- [[column.CODE, column.NAME, column.TITLE] for column in group_nodes],
60
+ [[column.code, column.name, column.title] for column in group_nodes],
61
61
  )
62
62
 
63
63
 
@@ -35,7 +35,7 @@ metrics_typer = typer.Typer(
35
35
 
36
36
  @metrics_typer.command("list")
37
37
  def list_metrics(
38
- query: Annotated[str | None, typer.Argument(help="正则关键词")] = None,
38
+ query: Annotated[str | None, typer.Option("-q", "--query", help="正则关键词")] = None,
39
39
  ) -> None:
40
40
  """列出所有指标。
41
41
 
@@ -50,7 +50,7 @@ def list_metrics(
50
50
  >>> data-ops-cli metrics list
51
51
 
52
52
  通过正则过滤指标
53
- >>> data-ops-cli metrics list "网元.*"
53
+ >>> data-ops-cli metrics list -q "网元.*"
54
54
  """
55
55
  try:
56
56
  group_nodes = release_list_list(MetaType.METRICS)
@@ -62,7 +62,7 @@ def list_metrics(
62
62
  group_nodes = filter_nodes_by_pattern(group_nodes, query)
63
63
  print_list(
64
64
  ["code", "title", "subType"],
65
- [[column.CODE, column.TITLE, column.SUB_TYPE or "atomic"] for column in group_nodes],
65
+ [[column.code, column.title, column.subType or "atomic"] for column in group_nodes],
66
66
  )
67
67
 
68
68
 
@@ -28,7 +28,7 @@ report_typer = typer.Typer(name="report", help="Manage reports", no_args_is_help
28
28
 
29
29
  @report_typer.command("list", rich_help_panel="报告查询")
30
30
  def list_reports(
31
- query: Annotated[str | None, typer.Argument(help="正则关键词")] = None,
31
+ query: Annotated[str | None, typer.Option("-q", "--query", help="正则关键词")] = None,
32
32
  ) -> None:
33
33
  """列出所有报告。
34
34
 
@@ -42,7 +42,7 @@ def list_reports(
42
42
  >>> data-ops-cli report list
43
43
 
44
44
  通过正则关键词过滤报告
45
- >>> data-ops-cli report list "daily.*"
45
+ >>> data-ops-cli report list -q "daily.*"
46
46
  """
47
47
  try:
48
48
  group_nodes = release_list_list(MetaType.REPORT)
@@ -55,7 +55,7 @@ def list_reports(
55
55
 
56
56
  print_list(
57
57
  ["code", "title", "subType"],
58
- [[column.CODE, column.TITLE, column.SUB_TYPE or "doc"] for column in group_nodes],
58
+ [[column.code, column.title, column.subType or "doc"] for column in group_nodes],
59
59
  )
60
60
 
61
61
 
@@ -11,8 +11,10 @@ from pathlib import Path
11
11
  from typing import Annotated
12
12
 
13
13
  import typer
14
+ from dataops_cli.cli.utils import paginate_with_line_numbers, print_list
14
15
  from dataops_sdk.exceptions import DataOpsError
15
- from dataops_sdk.schemas.skill import MetaSkillSubType
16
+ from dataops_sdk.schemas.enums import MetaType
17
+ from dataops_sdk.schemas.skill import MetaSkillFileSubType, MetaSkillSubType
16
18
  from dataops_sdk.services import (
17
19
  SkillPackValidationError,
18
20
  service_delete_skill,
@@ -29,11 +31,10 @@ from dataops_sdk.services.skill import (
29
31
  service_skill_get_subfile_by_name,
30
32
  )
31
33
  from dataops_sdk.tiptap import TipTapTool
34
+ from dataops_sdk.tiptap.constants import TableStyle
32
35
  from pydantic_core import from_json
33
36
  from rich.console import Console
34
37
 
35
- from dataops_cli.cli.utils import paginate_with_line_numbers, print_list
36
-
37
38
  # ---------------------------------------------------------------------------
38
39
  # CLI 命令
39
40
  # ---------------------------------------------------------------------------
@@ -49,6 +50,7 @@ skill_file_typer = typer.Typer(
49
50
  no_args_is_help=True,
50
51
  )
51
52
  skill_typer.add_typer(skill_file_typer)
53
+ MAKRDOWN_TABLE_STYLE = TableStyle.MARKDOWN
52
54
 
53
55
 
54
56
  @skill_typer.command("list")
@@ -76,31 +78,44 @@ def list_cmd(
76
78
 
77
79
  print_list(
78
80
  ("name", "title", "subType", "remark"),
79
- [[it.NAME, it.TITLE, it.SUB_TYPE or "", it.REMARK or ""] for it in items],
81
+ [[it.name, it.title, it.subType or "", it.remark or ""] for it in items],
80
82
  )
81
83
 
82
84
 
83
85
  @skill_typer.command("detail", no_args_is_help=True)
84
86
  def detail_cmd(
85
- name: Annotated[str | None, typer.Argument(help="技能名称")],
87
+ name: Annotated[str, typer.Argument(help="技能名称")],
88
+ path: Annotated[str | None, typer.Argument(help="文件路径")] = None,
86
89
  start: Annotated[int | None, typer.Option("--start", help="起始位置", min=1)] = None,
87
90
  size: Annotated[int | None, typer.Option("--size", help="读取长度", min=1)] = None,
88
91
  ) -> None:
89
92
  """查看技能详情。
90
93
 
91
94
  Examples:
92
- >>> data-ops-cli skill detail --code my-skill
93
- >>> data-ops-cli skill detail --name my-skill --full
95
+ 获取 my-skill 技能文档
96
+ >>> data-ops-cli skill detail my-skill
97
+ 获取 my-skill 技能 scripts/main.py 文件详情
98
+ >>> data-ops-cli skill detail my-skill scripts/main.py
94
99
  """
95
100
  try:
96
- meta = service_get_skill_by_name(name)
101
+ meta = service_get_skill_by_name(name, path=path)
97
102
  except DataOpsError as e:
98
103
  typer.echo(f"错误: {e.message}")
99
104
  raise typer.Exit(code=1) from None
100
105
 
101
- content = TipTapTool().serialize(meta.data.editor)
106
+ add_line_num = False
107
+ if meta.type == MetaType.SKILL.value or (
108
+ meta.type == MetaType.SKILL_FILE.value and meta.subType == MetaSkillFileSubType.DOC.value
109
+ ):
110
+ content = TipTapTool(table_style=MAKRDOWN_TABLE_STYLE).serialize(meta.data.editor)
111
+ add_line_num = True
112
+ elif meta.type == MetaType.SKILL_FILE.value and meta.subType == MetaSkillFileSubType.CODE.value:
113
+ add_line_num = True
114
+ content = meta.data.content
102
115
 
103
- print(paginate_with_line_numbers(content, start=start, size=size))
116
+ if add_line_num:
117
+ content = paginate_with_line_numbers(content, start=start, size=size)
118
+ print(content)
104
119
 
105
120
 
106
121
  @skill_typer.command("upload", no_args_is_help=True)
@@ -248,7 +263,7 @@ def files_cmd(
248
263
  """列出某技能下的所有子文件。
249
264
 
250
265
  Examples:
251
- >>> data-ops-cli skill files --skill-id <id>
266
+ >>> data-ops-cli skill files my-skills
252
267
  """
253
268
  try:
254
269
  items = service_list_skill_files(name)
@@ -262,43 +277,6 @@ def files_cmd(
262
277
  print("\n".join(it.DIGEST for it in items))
263
278
 
264
279
 
265
- @skill_file_typer.command("detail")
266
- def files_detail_cmd(
267
- name: Annotated[str, typer.Argument(help="技能名称")],
268
- path: Annotated[str, typer.Argument(help="子文件路径")],
269
- start: Annotated[int | None, typer.Option("--start", help="起始位置", min=1)] = None,
270
- size: Annotated[int | None, typer.Option("--size", help="读取长度", min=1)] = None,
271
- ) -> None:
272
- """获取某技能下某子文件的详细信息。
273
-
274
- Examples:
275
- >>> data-ops-cli skill files detail <skill-name> scripts/main.py
276
- """
277
- try:
278
- meta = service_skill_get_subfile_by_name(name, path)
279
- except DataOpsError as e:
280
- typer.echo(f"错误: {e.message}")
281
- raise typer.Exit(code=1) from None
282
- content = None
283
- add_line_num = False
284
- if meta.subType == "doc":
285
- add_line_num = True
286
- content = TipTapTool().serialize(meta.data.get("editor", None))
287
- elif meta.subType == "image":
288
- raise NotImplementedError("不支持查看图片")
289
- elif meta.subType == "code":
290
- add_line_num = True
291
- content = meta.data.get("content", None)
292
- else:
293
- raise NotImplementedError(f"未知的子文件类型 {meta.subType}")
294
- if content is None:
295
- print("未查询到子文件内容")
296
-
297
- if add_line_num:
298
- content = paginate_with_line_numbers(content, start=start, size=size)
299
- print(content)
300
-
301
-
302
280
  @skill_file_typer.command("upload", no_args_is_help=True)
303
281
  def upload_sub_file_cmd(
304
282
  name: Annotated[str, typer.Argument(help="技能名称")],
@@ -43,7 +43,7 @@ config_typer.add_typer(column_typer)
43
43
  @table_typer.command("list")
44
44
  def list_table(
45
45
  datasource: Annotated[str, typer.Argument(help="数据源")],
46
- query: Annotated[str | None, typer.Argument(help="表名关键字")] = None,
46
+ query: Annotated[str | None, typer.Option("-q", "--query", help="表名关键字")] = None,
47
47
  ) -> None:
48
48
  """列出数据源中的表列表。
49
49
 
@@ -58,10 +58,10 @@ def list_table(
58
58
  >>> data-ops-cli table list mydatasource
59
59
 
60
60
  # 列出数据源中名称包含 "user" 的表
61
- >>> data-ops-cli table list mydatasource user
61
+ >>> data-ops-cli table list mydatasource -q user
62
62
 
63
63
  # 使用正则过滤表名
64
- >>> data-ops-cli table list mydatasource "^user_.*"
64
+ >>> data-ops-cli table list mydatasource -q "^user_.*"
65
65
  """
66
66
  try:
67
67
  group_nodes = service_list_tables(datasource)
@@ -77,7 +77,7 @@ def list_table(
77
77
  group_nodes = filter_nodes_by_pattern(group_nodes, query)
78
78
  print_list(
79
79
  ["code", "name", "alias", "remark"],
80
- [[column.CODE, column.NAME, column.TITLE, column.REMARK] for column in group_nodes],
80
+ [[column.code, column.name, column.title, column.remark] for column in group_nodes],
81
81
  )
82
82
 
83
83
 
@@ -50,7 +50,7 @@ def list_widget(
50
50
 
51
51
  print_list(
52
52
  ["code", "title", "subType", "remark"],
53
- [[column.CODE, column.TITLE, column.SUB_TYPE, column.REMARK] for column in group_nodes],
53
+ [[column.code, column.title, column.subType, column.REMARK] for column in group_nodes],
54
54
  )
55
55
 
56
56
 
@@ -69,7 +69,7 @@ def list_workflow(
69
69
 
70
70
  print_list(
71
71
  ["code", "title", "subType", "remark"],
72
- [[column.CODE, column.TITLE, column.SUB_TYPE, column.REMARK] for column in group_nodes],
72
+ [[column.code, column.title, column.subType, column.remark] for column in group_nodes],
73
73
  )
74
74
 
75
75
 
File without changes