data-ops-cli 0.2.3__tar.gz → 0.3.0__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 (98) hide show
  1. data_ops_cli-0.3.0/PKG-INFO +11 -0
  2. data_ops_cli-0.3.0/pyproject.toml +37 -0
  3. data_ops_cli-0.3.0/src/data_ops_cli.egg-info/PKG-INFO +11 -0
  4. data_ops_cli-0.3.0/src/data_ops_cli.egg-info/SOURCES.txt +33 -0
  5. data_ops_cli-0.3.0/src/data_ops_cli.egg-info/requires.txt +7 -0
  6. data_ops_cli-0.3.0/src/dataops_cli/__init__.py +11 -0
  7. data_ops_cli-0.3.0/src/dataops_cli/_compat.py +53 -0
  8. data_ops_cli-0.3.0/src/dataops_cli/cli/alarm.py +381 -0
  9. data_ops_cli-0.3.0/src/dataops_cli/cli/api.py +227 -0
  10. {data_ops_cli-0.2.3 → data_ops_cli-0.3.0}/src/dataops_cli/cli/auth.py +19 -15
  11. {data_ops_cli-0.2.3 → data_ops_cli-0.3.0}/src/dataops_cli/cli/data_table.py +29 -21
  12. {data_ops_cli-0.2.3 → data_ops_cli-0.3.0}/src/dataops_cli/cli/dataset.py +74 -8
  13. {data_ops_cli-0.2.3 → data_ops_cli-0.3.0}/src/dataops_cli/cli/datasource.py +22 -21
  14. {data_ops_cli-0.2.3 → data_ops_cli-0.3.0}/src/dataops_cli/cli/dict_.py +8 -8
  15. {data_ops_cli-0.2.3 → data_ops_cli-0.3.0}/src/dataops_cli/cli/factory.py +9 -2
  16. data_ops_cli-0.3.0/src/dataops_cli/cli/hazard.py +364 -0
  17. {data_ops_cli-0.2.3 → data_ops_cli-0.3.0}/src/dataops_cli/cli/metrics.py +9 -9
  18. {data_ops_cli-0.2.3 → data_ops_cli-0.3.0}/src/dataops_cli/cli/ref.py +3 -3
  19. {data_ops_cli-0.2.3 → data_ops_cli-0.3.0}/src/dataops_cli/cli/report.py +10 -10
  20. data_ops_cli-0.3.0/src/dataops_cli/cli/skill.py +303 -0
  21. {data_ops_cli-0.2.3 → data_ops_cli-0.3.0}/src/dataops_cli/cli/table.py +111 -36
  22. {data_ops_cli-0.2.3 → data_ops_cli-0.3.0}/src/dataops_cli/cli/utils.py +14 -0
  23. data_ops_cli-0.3.0/src/dataops_cli/cli/widget.py +471 -0
  24. {data_ops_cli-0.2.3 → data_ops_cli-0.3.0}/src/dataops_cli/cli/workflow.py +85 -10
  25. data_ops_cli-0.3.0/src/dataops_cli/exceptions.py +8 -0
  26. data_ops_cli-0.3.0/src/dataops_cli/runner.py +8 -0
  27. data_ops_cli-0.3.0/src/dataops_cli/schems.py +8 -0
  28. data_ops_cli-0.3.0/src/dataops_cli/sdk.py +8 -0
  29. data_ops_cli-0.3.0/src/dataops_cli/session.py +8 -0
  30. data_ops_cli-0.3.0/src/dataops_cli/utils.py +8 -0
  31. data_ops_cli-0.2.3/PKG-INFO +0 -18
  32. data_ops_cli-0.2.3/README.md +0 -41
  33. data_ops_cli-0.2.3/pyproject.toml +0 -63
  34. data_ops_cli-0.2.3/src/data_ops_cli.egg-info/PKG-INFO +0 -18
  35. data_ops_cli-0.2.3/src/data_ops_cli.egg-info/SOURCES.txt +0 -78
  36. data_ops_cli-0.2.3/src/data_ops_cli.egg-info/requires.txt +0 -15
  37. data_ops_cli-0.2.3/src/dataops_cli/__init__.py +0 -1
  38. data_ops_cli-0.2.3/src/dataops_cli/cli/widget.py +0 -60
  39. data_ops_cli-0.2.3/src/dataops_cli/constants.py +0 -8
  40. data_ops_cli-0.2.3/src/dataops_cli/exceptions.py +0 -31
  41. data_ops_cli-0.2.3/src/dataops_cli/runner/__init__.py +0 -36
  42. data_ops_cli-0.2.3/src/dataops_cli/runner/schemas/nacos/__init__.py +0 -5
  43. data_ops_cli-0.2.3/src/dataops_cli/runner/schemas/nacos/config.py +0 -40
  44. data_ops_cli-0.2.3/src/dataops_cli/runner/schemas/nacos/constants.py +0 -235
  45. data_ops_cli-0.2.3/src/dataops_cli/runner/schemas/nacos/instance.py +0 -103
  46. data_ops_cli-0.2.3/src/dataops_cli/runner/schemas/nacos/nacos_exception.py +0 -44
  47. data_ops_cli-0.2.3/src/dataops_cli/runner/schemas/nacos/naming_param.py +0 -61
  48. data_ops_cli-0.2.3/src/dataops_cli/runner/schemas/nacos/naming_request.py +0 -84
  49. data_ops_cli-0.2.3/src/dataops_cli/runner/schemas/nacos/naming_response.py +0 -51
  50. data_ops_cli-0.2.3/src/dataops_cli/runner/schemas/nacos/preserved_metadata_key.py +0 -10
  51. data_ops_cli-0.2.3/src/dataops_cli/runner/schemas/nacos/service.py +0 -119
  52. data_ops_cli-0.2.3/src/dataops_cli/runner/utils/__init__.py +0 -35
  53. data_ops_cli-0.2.3/src/dataops_cli/runner/utils/common.py +0 -209
  54. data_ops_cli-0.2.3/src/dataops_cli/runner/utils/dbConn_base.py +0 -257
  55. data_ops_cli-0.2.3/src/dataops_cli/runner/utils/dbConn_sync.py +0 -419
  56. data_ops_cli-0.2.3/src/dataops_cli/runner/utils/duckdb_manager.py +0 -203
  57. data_ops_cli-0.2.3/src/dataops_cli/runner/utils/log.py +0 -48
  58. data_ops_cli-0.2.3/src/dataops_cli/runner/utils/nacos.py +0 -99
  59. data_ops_cli-0.2.3/src/dataops_cli/runner/utils/neo4j_sync.py +0 -231
  60. data_ops_cli-0.2.3/src/dataops_cli/schems/__init__.py +0 -27
  61. data_ops_cli-0.2.3/src/dataops_cli/schems/data_table.py +0 -436
  62. data_ops_cli-0.2.3/src/dataops_cli/schems/datasource.py +0 -25
  63. data_ops_cli-0.2.3/src/dataops_cli/schems/dict_.py +0 -13
  64. data_ops_cli-0.2.3/src/dataops_cli/schems/enums.py +0 -116
  65. data_ops_cli-0.2.3/src/dataops_cli/schems/group.py +0 -40
  66. data_ops_cli-0.2.3/src/dataops_cli/schems/meta.py +0 -173
  67. data_ops_cli-0.2.3/src/dataops_cli/schems/query.py +0 -174
  68. data_ops_cli-0.2.3/src/dataops_cli/schems/report.py +0 -21
  69. data_ops_cli-0.2.3/src/dataops_cli/schems/table.py +0 -65
  70. data_ops_cli-0.2.3/src/dataops_cli/schems/user.py +0 -52
  71. data_ops_cli-0.2.3/src/dataops_cli/schems/widget.py +0 -555
  72. data_ops_cli-0.2.3/src/dataops_cli/schems/workflow.py +0 -55
  73. data_ops_cli-0.2.3/src/dataops_cli/sdk/__init__.py +0 -35
  74. data_ops_cli-0.2.3/src/dataops_cli/sdk/auth.py +0 -120
  75. data_ops_cli-0.2.3/src/dataops_cli/sdk/data_table.py +0 -231
  76. data_ops_cli-0.2.3/src/dataops_cli/sdk/dataset.py +0 -54
  77. data_ops_cli-0.2.3/src/dataops_cli/sdk/datasource.py +0 -53
  78. data_ops_cli-0.2.3/src/dataops_cli/sdk/dict_.py +0 -69
  79. data_ops_cli-0.2.3/src/dataops_cli/sdk/meta.py +0 -510
  80. data_ops_cli-0.2.3/src/dataops_cli/sdk/ref.py +0 -66
  81. data_ops_cli-0.2.3/src/dataops_cli/sdk/report.py +0 -14
  82. data_ops_cli-0.2.3/src/dataops_cli/sdk/table.py +0 -211
  83. data_ops_cli-0.2.3/src/dataops_cli/sdk/workflow.py +0 -12
  84. data_ops_cli-0.2.3/src/dataops_cli/session.py +0 -214
  85. data_ops_cli-0.2.3/src/dataops_cli/tiptap/__init__.py +0 -30
  86. data_ops_cli-0.2.3/src/dataops_cli/tiptap/builder.py +0 -75
  87. data_ops_cli-0.2.3/src/dataops_cli/tiptap/constants.py +0 -133
  88. data_ops_cli-0.2.3/src/dataops_cli/tiptap/models.py +0 -43
  89. data_ops_cli-0.2.3/src/dataops_cli/tiptap/parse_utils.py +0 -889
  90. data_ops_cli-0.2.3/src/dataops_cli/tiptap/render_utils.py +0 -846
  91. data_ops_cli-0.2.3/src/dataops_cli/tiptap/renderers.py +0 -51
  92. data_ops_cli-0.2.3/src/dataops_cli/tiptap/tool.py +0 -839
  93. data_ops_cli-0.2.3/src/dataops_cli/utils.py +0 -122
  94. {data_ops_cli-0.2.3 → data_ops_cli-0.3.0}/setup.cfg +0 -0
  95. {data_ops_cli-0.2.3 → data_ops_cli-0.3.0}/src/data_ops_cli.egg-info/dependency_links.txt +0 -0
  96. {data_ops_cli-0.2.3 → data_ops_cli-0.3.0}/src/data_ops_cli.egg-info/entry_points.txt +0 -0
  97. {data_ops_cli-0.2.3 → data_ops_cli-0.3.0}/src/data_ops_cli.egg-info/top_level.txt +0 -0
  98. {data_ops_cli-0.2.3 → data_ops_cli-0.3.0}/src/dataops_cli/cli/__init__.py +0 -0
@@ -0,0 +1,11 @@
1
+ Metadata-Version: 2.4
2
+ Name: data-ops-cli
3
+ Version: 0.3.0
4
+ Summary: Command-line wrapper around dataops_sdk for the DataOps platform.
5
+ Requires-Python: >=3.11
6
+ Requires-Dist: dataops_sdk[runner]<1.0,>=0.1.0
7
+ Requires-Dist: typer
8
+ Requires-Dist: rich
9
+ Provides-Extra: dev
10
+ Requires-Dist: pytest; extra == "dev"
11
+ Requires-Dist: ruff; extra == "dev"
@@ -0,0 +1,37 @@
1
+ [build-system]
2
+ requires = ["setuptools>=61", "wheel"]
3
+ build-backend = "setuptools.build_meta"
4
+
5
+ [project]
6
+ name = "data-ops-cli"
7
+ dynamic = ["version"]
8
+ description = "Command-line wrapper around dataops_sdk for the DataOps platform."
9
+ requires-python = ">=3.11"
10
+ dependencies = [
11
+ "dataops_sdk[runner]>=0.1.0,<1.0",
12
+ "typer",
13
+ "rich",
14
+ ]
15
+
16
+ [project.scripts]
17
+ data-ops-cli = "dataops_cli.cli:app"
18
+
19
+ [project.optional-dependencies]
20
+ dev = ["pytest", "ruff"]
21
+
22
+ [tool.uv.sources]
23
+ dataops_sdk = { workspace = true }
24
+
25
+ [tool.setuptools]
26
+ package-dir = {"" = "src"}
27
+ include-package-data = true
28
+
29
+ [tool.setuptools.dynamic]
30
+ version = {attr = "dataops_cli.__version__"}
31
+
32
+ [tool.setuptools.packages.find]
33
+ where = ["src"]
34
+ include = ["dataops_cli*"]
35
+
36
+ [tool.setuptools.package-data]
37
+ dataops_cli = ["py.typed"]
@@ -0,0 +1,11 @@
1
+ Metadata-Version: 2.4
2
+ Name: data-ops-cli
3
+ Version: 0.3.0
4
+ Summary: Command-line wrapper around dataops_sdk for the DataOps platform.
5
+ Requires-Python: >=3.11
6
+ Requires-Dist: dataops_sdk[runner]<1.0,>=0.1.0
7
+ Requires-Dist: typer
8
+ Requires-Dist: rich
9
+ Provides-Extra: dev
10
+ Requires-Dist: pytest; extra == "dev"
11
+ Requires-Dist: ruff; extra == "dev"
@@ -0,0 +1,33 @@
1
+ pyproject.toml
2
+ src/data_ops_cli.egg-info/PKG-INFO
3
+ src/data_ops_cli.egg-info/SOURCES.txt
4
+ src/data_ops_cli.egg-info/dependency_links.txt
5
+ src/data_ops_cli.egg-info/entry_points.txt
6
+ src/data_ops_cli.egg-info/requires.txt
7
+ src/data_ops_cli.egg-info/top_level.txt
8
+ src/dataops_cli/__init__.py
9
+ src/dataops_cli/_compat.py
10
+ src/dataops_cli/exceptions.py
11
+ src/dataops_cli/runner.py
12
+ src/dataops_cli/schems.py
13
+ src/dataops_cli/sdk.py
14
+ src/dataops_cli/session.py
15
+ src/dataops_cli/utils.py
16
+ src/dataops_cli/cli/__init__.py
17
+ src/dataops_cli/cli/alarm.py
18
+ src/dataops_cli/cli/api.py
19
+ src/dataops_cli/cli/auth.py
20
+ src/dataops_cli/cli/data_table.py
21
+ src/dataops_cli/cli/dataset.py
22
+ src/dataops_cli/cli/datasource.py
23
+ src/dataops_cli/cli/dict_.py
24
+ src/dataops_cli/cli/factory.py
25
+ src/dataops_cli/cli/hazard.py
26
+ src/dataops_cli/cli/metrics.py
27
+ src/dataops_cli/cli/ref.py
28
+ src/dataops_cli/cli/report.py
29
+ src/dataops_cli/cli/skill.py
30
+ src/dataops_cli/cli/table.py
31
+ src/dataops_cli/cli/utils.py
32
+ src/dataops_cli/cli/widget.py
33
+ src/dataops_cli/cli/workflow.py
@@ -0,0 +1,7 @@
1
+ dataops_sdk[runner]<1.0,>=0.1.0
2
+ typer
3
+ rich
4
+
5
+ [dev]
6
+ pytest
7
+ ruff
@@ -0,0 +1,11 @@
1
+ """CLI package for DataOps.
2
+
3
+ .. deprecated::
4
+ Importing ``dataops_cli.sdk`` / ``dataops_cli.schems`` / ``dataops_cli.runner`` /
5
+ ``dataops_cli.exceptions`` / ``dataops_cli.session`` / ``dataops_cli.utils`` directly
6
+ is deprecated; use the new ``dataops_sdk`` package instead. The CLI itself
7
+ (``dataops_cli.cli``) is unchanged. The deprecation shims will be removed in
8
+ ``dataops_cli`` 1.0.
9
+ """
10
+
11
+ __version__ = "0.3.0"
@@ -0,0 +1,53 @@
1
+ """Build a deprecation-shim module via PEP 562 ``__getattr__``.
2
+
3
+ Each top-level shim (``dataops_cli.sdk`` / ``dataops_cli.schems`` / ...) is a tiny
4
+ file whose body is a single call to :func:`make_shim`. The returned namespace
5
+ exposes ``__all__`` and a ``__getattr__`` that proxies to the underlying
6
+ ``dataops_sdk`` module while emitting a single ``DeprecationWarning`` per
7
+ attribute name (so logging stays bounded).
8
+
9
+ Removed in ``dataops_cli`` 1.0.
10
+ """
11
+
12
+ from __future__ import annotations
13
+
14
+ import importlib
15
+ import sys
16
+ import warnings
17
+ from types import ModuleType
18
+ from typing import Any
19
+
20
+ _OLD_TO_NEW = {
21
+ "dataops_cli.sdk": "dataops_sdk.services",
22
+ "dataops_cli.schems": "dataops_sdk.schemas",
23
+ "dataops_cli.runner": "dataops_sdk.runner",
24
+ "dataops_cli.exceptions": "dataops_sdk.exceptions",
25
+ "dataops_cli.session": "dataops_sdk.session",
26
+ "dataops_cli.utils": "dataops_sdk.utils",
27
+ }
28
+
29
+
30
+ def make_shim(old_path: str) -> ModuleType:
31
+ """Create (and register in ``sys.modules``) a shim module proxying to ``new_path``."""
32
+ new_path = _OLD_TO_NEW[old_path]
33
+ target = importlib.import_module(new_path)
34
+ warned: set[str] = set()
35
+
36
+ def __getattr__(name: str) -> Any:
37
+ if name not in warned:
38
+ warned.add(name)
39
+ warnings.warn(
40
+ f"Importing '{name}' from '{old_path}' is deprecated; "
41
+ f"import it from '{new_path}' instead. "
42
+ "This shim will be removed in dataops_cli 1.0.",
43
+ DeprecationWarning,
44
+ stacklevel=2,
45
+ )
46
+ return getattr(target, name)
47
+
48
+ module = ModuleType(old_path)
49
+ module.__getattr__ = __getattr__ # type: ignore[attr-defined]
50
+ module.__all__ = getattr(target, "__all__", []) # type: ignore[attr-defined]
51
+ module.__dir__ = lambda: list(dir(target)) # type: ignore[attr-defined]
52
+ sys.modules[old_path] = module
53
+ return module
@@ -0,0 +1,381 @@
1
+ """告警管理模块.
2
+
3
+ 提供告警规则的查询与配置能力,覆盖后端 /alarm/rule/* 接口。
4
+
5
+ - 服务层函数 (service_*):纯 Python 接口,返回原始数据
6
+ - CLI 命令:基于服务层的薄包装,负责格式化输出
7
+ """
8
+
9
+ import json
10
+ from typing import Annotated, Any, Optional
11
+
12
+ import typer
13
+ from pydantic_core import to_json
14
+ from rich.console import Console
15
+ from rich.table import Table
16
+
17
+ from dataops_cli.cli.utils import print_list
18
+ from dataops_sdk.exceptions import DataOpsError
19
+ from dataops_sdk.schemas.query import SqlQueryParam
20
+ from dataops_sdk.services.alarm import (
21
+ service_count_alarm_action,
22
+ service_count_alarm_rule_matches,
23
+ service_count_alarm_rules,
24
+ service_count_alarm_specs,
25
+ service_find_alarm_table_data,
26
+ service_find_meta_by_codes,
27
+ service_get_alarm_rule_enums,
28
+ service_get_alarm_table_columns,
29
+ service_get_rel_table_columns,
30
+ service_list_alarm_action,
31
+ service_list_alarm_rule_matches,
32
+ service_list_alarm_rules,
33
+ service_list_alarm_specs,
34
+ )
35
+
36
+ # ---------------------------------------------------------------------------
37
+ # CLI 命令(薄包装,负责输出渲染)
38
+ # ---------------------------------------------------------------------------
39
+
40
+ alarm_typer = typer.Typer(name="alarm", help="告警相关命令", no_args_is_help=True)
41
+ alarm_rule_typer = typer.Typer(name="rule", help="告警规则命令", no_args_is_help=True)
42
+ alarm_spec_typer = typer.Typer(name="spec", help="告警专业命令", no_args_is_help=True)
43
+ alarm_action_typer = typer.Typer(name="action", help="告警动作命令", no_args_is_help=True)
44
+ rule_match_typer = typer.Typer(name="match", help="规则匹配命令", no_args_is_help=True)
45
+ alarm_typer.add_typer(alarm_rule_typer, no_args_is_help=True)
46
+ alarm_typer.add_typer(alarm_spec_typer, no_args_is_help=True)
47
+ alarm_rule_typer.add_typer(rule_match_typer, no_args_is_help=True)
48
+ alarm_typer.add_typer(alarm_action_typer, no_args_is_help=True)
49
+
50
+
51
+ def _safe_str(value: Any) -> str:
52
+ if value is None:
53
+ return ""
54
+ if isinstance(value, (dict, list)):
55
+ return to_json(value).decode("utf-8")
56
+ return str(value)
57
+
58
+
59
+ def _extract_column_list(data: Any) -> list:
60
+ """从响应中提取列数组。
61
+
62
+ 后端返回可能是:
63
+ - list[...] 直接列表
64
+ - dict {"columns": [...], "indexes": [...]} 嵌套结构
65
+ - None / 其他 空
66
+ """
67
+ if isinstance(data, list):
68
+ return data
69
+ if isinstance(data, dict):
70
+ columns = data.get("columns")
71
+ if isinstance(columns, list):
72
+ return columns
73
+ return []
74
+
75
+
76
+ def _print_column_list(data: Any) -> None:
77
+ """统一渲染列数组(list[dict] → 平面表;其他 → JSON)."""
78
+ columns = _extract_column_list(data)
79
+ if not columns:
80
+ print("(空)")
81
+ return
82
+ if isinstance(columns[0], dict):
83
+ headers = list(columns[0].keys())
84
+ rows = [[_safe_str(c.get(h)) for h in headers] for c in columns]
85
+ print_list(headers, rows)
86
+ else:
87
+ print(to_json(columns).decode("utf-8"))
88
+
89
+
90
+ @rule_match_typer.command("count", help="查询告警匹配规则数量")
91
+ def count_alarm_rules_match(
92
+ spec: Annotated[list[str], typer.Option(help="专业值", default_factory=list)],
93
+ query: Annotated[Optional[str], typer.Option("-q", "--query", help="搜索关键字")] = None,
94
+ enabled: Annotated[Optional[bool], typer.Option(help="启用状态")] = None,
95
+ ):
96
+ try:
97
+ total = service_count_alarm_rule_matches(query, enabled, spec)
98
+ except DataOpsError as e:
99
+ typer.echo(f"错误: {e.message}")
100
+ raise typer.Exit(code=1) from None
101
+ print(total)
102
+
103
+
104
+ @rule_match_typer.command("list", help="查询告警匹配规则")
105
+ def list_alarm_rules_match(
106
+ spec: Annotated[list[str], typer.Option(help="专业值", default_factory=list)],
107
+ page: Annotated[int, typer.Option("-p", "--page", help="页码")] = 0,
108
+ size: Annotated[int, typer.Option("-s", "--size", help="每页条数")] = 20,
109
+ query: Annotated[Optional[str], typer.Option("-q", "--query", help="搜索关键字")] = None,
110
+ enabled: Annotated[Optional[bool], typer.Option(help="启用状态")] = None,
111
+ ):
112
+ try:
113
+ group_nodes = service_list_alarm_rule_matches(page, size, query, enabled, spec)
114
+ except DataOpsError as e:
115
+ typer.echo(f"错误: {e.message}")
116
+ raise typer.Exit(code=1) from None
117
+
118
+ if not group_nodes:
119
+ print("未查询到匹配告警规则")
120
+ return
121
+ print_list(
122
+ [
123
+ "告警匹配规则名称",
124
+ "规则类型(值)",
125
+ "启用状态",
126
+ "所属区域",
127
+ "专业类型(值)",
128
+ "创建人",
129
+ "更新时间",
130
+ ],
131
+ [
132
+ [
133
+ column.TITLE,
134
+ f"{column.N_RULE_TYPE}({column.RULE_TYPE})",
135
+ column.N_IS_ENABLED,
136
+ column.AREA,
137
+ f"{column.N_SPEC_TYPE}({column.SPEC_TYPE})",
138
+ column.CREATE_USER,
139
+ column.LAST_MODIFY_TIME,
140
+ ]
141
+ for column in group_nodes
142
+ ],
143
+ )
144
+
145
+
146
+ @alarm_spec_typer.command("list", help="查询告警专业")
147
+ def list_alarm_specs(
148
+ page: Annotated[int, typer.Option("-p", "--page", help="页码")] = 0,
149
+ size: Annotated[int, typer.Option("-s", "--size", help="每页条数")] = 20,
150
+ query: Annotated[Optional[str], typer.Option("-q", "--query", help="搜索关键字")] = None,
151
+ active: Annotated[Optional[bool], typer.Option(help="启用状态")] = None,
152
+ ):
153
+ query_param = SqlQueryParam()
154
+ if active is not None:
155
+ query_param.varMap["isEnabled"] = "1" if active else "0"
156
+ if query:
157
+ query_param.add_like("title", query, "mrl")
158
+ group_nodes = service_list_alarm_specs(page, size, query_param)
159
+
160
+ print_list(
161
+ ["专业名称", "值", "行业", "启用状态", "创建人", "更新时间"],
162
+ [
163
+ [
164
+ column.TITLE,
165
+ column.CODE,
166
+ column.N_INDUSTRY,
167
+ column.N_IS_ENABLED,
168
+ column.CREATE_USER,
169
+ column.LAST_MODIFY_TIME,
170
+ ]
171
+ for column in group_nodes
172
+ ],
173
+ )
174
+
175
+
176
+ @alarm_spec_typer.command("count", help="查询告警专业数量")
177
+ def count_alarm_specs(
178
+ query: Annotated[Optional[str], typer.Option("-q", "--query", help="搜索关键字")] = None,
179
+ enabled: Annotated[Optional[bool], typer.Option(help="启用状态")] = None,
180
+ ):
181
+ total = service_count_alarm_specs(query, enabled)
182
+ print(total)
183
+
184
+
185
+ @alarm_rule_typer.command("list", help="查询告警规则")
186
+ def list_alarm_rules(
187
+ page: Annotated[int, typer.Option("-p", "--page", help="页码")] = 0,
188
+ size: Annotated[int, typer.Option("-s", "--size", help="每页条数")] = 20,
189
+ query: Annotated[Optional[str], typer.Option("-q", "--query", help="搜索关键字")] = None,
190
+ enabled: Annotated[Optional[bool], typer.Option(help="启用状态")] = None,
191
+ ):
192
+ group_nodes = service_list_alarm_rules(page, size, query, enabled)
193
+
194
+ print_list(
195
+ ["规则名称", "值", "启用状态", "创建人", "更新时间"],
196
+ [
197
+ [
198
+ column.TITLE,
199
+ column.CODE,
200
+ column.N_IS_ENABLED,
201
+ column.CREATE_USER,
202
+ column.LAST_MODIFY_TIME,
203
+ ]
204
+ for column in group_nodes
205
+ ],
206
+ )
207
+
208
+
209
+ @alarm_spec_typer.command("count", help="查询告警规则数量")
210
+ def count_alarm_specs(
211
+ query: Annotated[Optional[str], typer.Option("-q", "--query", help="搜索关键字")] = None,
212
+ enabled: Annotated[Optional[bool], typer.Option(help="启用状态")] = None,
213
+ ):
214
+ total = service_count_alarm_rules(query, enabled)
215
+ print(total)
216
+
217
+
218
+ @alarm_action_typer.command("list", help="查询告警动作")
219
+ def list_alarm_actions(
220
+ rule: Annotated[list[str], typer.Option(help="专业值", default_factory=list)],
221
+ page: Annotated[int, typer.Option("-p", "--page", help="页码")] = 0,
222
+ size: Annotated[int, typer.Option("-s", "--size", help="每页条数")] = 20,
223
+ query: Annotated[Optional[str], typer.Option("-q", "--query", help="搜索关键字")] = None,
224
+ enabled: Annotated[Optional[bool], typer.Option(help="启用状态")] = None,
225
+ ):
226
+ try:
227
+ group_nodes = service_list_alarm_action(page, size, query, enabled, rule)
228
+ except DataOpsError as e:
229
+ typer.echo(f"错误: {e.message}")
230
+ raise typer.Exit(code=1) from None
231
+
232
+ if not group_nodes:
233
+ print("未查询到匹配告警动作")
234
+ return
235
+ print_list(
236
+ [
237
+ "动作名称",
238
+ "值",
239
+ "规则类型(值)",
240
+ "启用状态",
241
+ "创建人",
242
+ "更新时间",
243
+ ],
244
+ [
245
+ [
246
+ column.TITLE,
247
+ column.CODE,
248
+ f"{column.N_RULE_TYPE}({column.RULE_TYPE})",
249
+ column.N_IS_ENABLED,
250
+ column.CREATE_USER,
251
+ column.LAST_MODIFY_TIME,
252
+ ]
253
+ for column in group_nodes
254
+ ],
255
+ )
256
+
257
+
258
+ @alarm_action_typer.command("count", help="查询告警动作数量")
259
+ def count_alarm_actions(
260
+ rule: Annotated[list[str], typer.Option(help="专业值", default_factory=list)],
261
+ query: Annotated[Optional[str], typer.Option("-q", "--query", help="搜索关键字")] = None,
262
+ enabled: Annotated[Optional[bool], typer.Option(help="启用状态")] = None,
263
+ ):
264
+ try:
265
+ total = service_count_alarm_action(query, enabled, rule)
266
+ except DataOpsError as e:
267
+ typer.echo(f"错误: {e.message}")
268
+ raise typer.Exit(code=1) from None
269
+ print(total)
270
+
271
+
272
+ @alarm_rule_typer.command("enums")
273
+ def get_alarm_rule_enums() -> None:
274
+ """获取告警规则枚举配置.
275
+
276
+ 示例:
277
+ >>> data-ops-cli alarm rule enums
278
+ """
279
+ try:
280
+ data = service_get_alarm_rule_enums()
281
+ except DataOpsError as e:
282
+ typer.echo(f"错误: {e.message}")
283
+ raise typer.Exit(code=1) from None
284
+
285
+ if not data:
286
+ print("(空)")
287
+ return
288
+
289
+ if isinstance(data, dict):
290
+ table = Table("key", "value", show_header=False)
291
+ for k, v in data.items():
292
+ table.add_row(k, _safe_str(v))
293
+ console = Console(no_color=True)
294
+ console.print(table)
295
+ else:
296
+ print(to_json(data).decode("utf-8"))
297
+
298
+
299
+ @alarm_rule_typer.command("find-meta-by-codes", no_args_is_help=True)
300
+ def find_meta_by_codes(
301
+ codes: Annotated[list[str], typer.Argument(help="告警规则编码列表")],
302
+ ) -> None:
303
+ """根据告警规则编码批量查询关联元数据.
304
+
305
+ 示例:
306
+ >>> data-ops-cli alarm rule find-meta-by-codes code1 code2
307
+ """
308
+ try:
309
+ data = service_find_meta_by_codes(list(codes))
310
+ except DataOpsError as e:
311
+ typer.echo(f"错误: {e.message}")
312
+ raise typer.Exit(code=1) from None
313
+
314
+ print(to_json(data).decode("utf-8"))
315
+
316
+
317
+ @alarm_rule_typer.command("alarm-columns", no_args_is_help=True)
318
+ def get_alarm_table_columns(
319
+ spec_type: Annotated[str, typer.Argument(help="告警规格类型")],
320
+ ) -> None:
321
+ """获取指定 specType 对应的告警表列定义.
322
+
323
+ 示例:
324
+ >>> data-ops-cli alarm rule alarm-columns MY_SPEC_TYPE
325
+ """
326
+ try:
327
+ columns = service_get_alarm_table_columns(spec_type)
328
+ except DataOpsError as e:
329
+ typer.echo(f"错误: {e.message}")
330
+ raise typer.Exit(code=1) from None
331
+
332
+ _print_column_list(columns)
333
+
334
+
335
+ @alarm_rule_typer.command("rel-columns", no_args_is_help=True)
336
+ def get_rel_table_columns(
337
+ code: Annotated[str, typer.Argument(help="告警规则编码")],
338
+ ) -> None:
339
+ """获取指定告警规则关联表列.
340
+
341
+ 示例:
342
+ >>> data-ops-cli alarm rule rel-columns rule_code_001
343
+ """
344
+ try:
345
+ columns = service_get_rel_table_columns(code)
346
+ except DataOpsError as e:
347
+ typer.echo(f"错误: {e.message}")
348
+ raise typer.Exit(code=1) from None
349
+
350
+ _print_column_list(columns)
351
+
352
+
353
+ @alarm_rule_typer.command("data", no_args_is_help=True)
354
+ def find_alarm_table_data(
355
+ code: Annotated[str, typer.Option(help="告警规则编码")],
356
+ query: Annotated[
357
+ str | None,
358
+ typer.Option(help="查询条件 JSON 字符串"),
359
+ ] = None,
360
+ ) -> None:
361
+ """查询告警表数据.
362
+
363
+ 示例:
364
+ >>> data-ops-cli alarm rule data --code rule_code_001
365
+
366
+ 带查询条件
367
+ >>> data-ops-cli alarm rule data --code rule_code_001 --query '{"date":"2026-07-16"}'
368
+ """
369
+ try:
370
+ query_dict = json.loads(query) if query else None
371
+ except json.JSONDecodeError as e:
372
+ typer.echo(f"错误: --query 不是合法 JSON: {e}")
373
+ raise typer.Exit(code=1) from None
374
+
375
+ try:
376
+ data = service_find_alarm_table_data(code, query_dict)
377
+ except DataOpsError as e:
378
+ typer.echo(f"错误: {e.message}")
379
+ raise typer.Exit(code=1) from None
380
+
381
+ print(to_json(data).decode("utf-8"))