dataops-sdk 0.3.0__py3-none-any.whl
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.
Potentially problematic release.
This version of dataops-sdk might be problematic. Click here for more details.
- dataops_sdk/__init__.py +84 -0
- dataops_sdk/constants.py +6 -0
- dataops_sdk/exceptions.py +31 -0
- dataops_sdk/runner/__init__.py +46 -0
- dataops_sdk/runner/datasource_factory.py +83 -0
- dataops_sdk/runner/schemas/nacos/__init__.py +5 -0
- dataops_sdk/runner/schemas/nacos/config.py +40 -0
- dataops_sdk/runner/schemas/nacos/constants.py +235 -0
- dataops_sdk/runner/schemas/nacos/instance.py +103 -0
- dataops_sdk/runner/schemas/nacos/nacos_exception.py +44 -0
- dataops_sdk/runner/schemas/nacos/naming_param.py +62 -0
- dataops_sdk/runner/schemas/nacos/naming_request.py +84 -0
- dataops_sdk/runner/schemas/nacos/naming_response.py +50 -0
- dataops_sdk/runner/schemas/nacos/preserved_metadata_key.py +10 -0
- dataops_sdk/runner/schemas/nacos/service.py +119 -0
- dataops_sdk/runner/utils/__init__.py +42 -0
- dataops_sdk/runner/utils/common.py +209 -0
- dataops_sdk/runner/utils/dbConn_base.py +256 -0
- dataops_sdk/runner/utils/dbConn_sync.py +485 -0
- dataops_sdk/runner/utils/duckdb_manager.py +203 -0
- dataops_sdk/runner/utils/file_transfer_base.py +307 -0
- dataops_sdk/runner/utils/ftp_file_transfer.py +242 -0
- dataops_sdk/runner/utils/log.py +50 -0
- dataops_sdk/runner/utils/nacos.py +96 -0
- dataops_sdk/runner/utils/neo4j_sync.py +236 -0
- dataops_sdk/runner/utils/queue_base.py +224 -0
- dataops_sdk/runner/utils/queue_kafka.py +150 -0
- dataops_sdk/runner/utils/sftp_file_transfer.py +243 -0
- dataops_sdk/schemas/__init__.py +32 -0
- dataops_sdk/schemas/alarm.py +38 -0
- dataops_sdk/schemas/api.py +37 -0
- dataops_sdk/schemas/data_table.py +437 -0
- dataops_sdk/schemas/datasource.py +26 -0
- dataops_sdk/schemas/dict_.py +13 -0
- dataops_sdk/schemas/enums.py +120 -0
- dataops_sdk/schemas/group.py +40 -0
- dataops_sdk/schemas/hazard.py +151 -0
- dataops_sdk/schemas/meta.py +175 -0
- dataops_sdk/schemas/query.py +175 -0
- dataops_sdk/schemas/report.py +22 -0
- dataops_sdk/schemas/skill.py +70 -0
- dataops_sdk/schemas/table.py +65 -0
- dataops_sdk/schemas/user.py +52 -0
- dataops_sdk/schemas/widget.py +651 -0
- dataops_sdk/schemas/workflow.py +63 -0
- dataops_sdk/services/__init__.py +110 -0
- dataops_sdk/services/alarm.py +324 -0
- dataops_sdk/services/api.py +28 -0
- dataops_sdk/services/auth.py +120 -0
- dataops_sdk/services/data_table.py +485 -0
- dataops_sdk/services/dataset.py +127 -0
- dataops_sdk/services/datasource.py +57 -0
- dataops_sdk/services/dict_.py +69 -0
- dataops_sdk/services/hazard.py +260 -0
- dataops_sdk/services/meta.py +523 -0
- dataops_sdk/services/metrics.py +42 -0
- dataops_sdk/services/ref.py +66 -0
- dataops_sdk/services/report.py +36 -0
- dataops_sdk/services/skill.py +276 -0
- dataops_sdk/services/table.py +340 -0
- dataops_sdk/services/widget.py +143 -0
- dataops_sdk/services/workflow.py +102 -0
- dataops_sdk/session.py +292 -0
- dataops_sdk/tiptap/__init__.py +30 -0
- dataops_sdk/tiptap/builder.py +75 -0
- dataops_sdk/tiptap/constants.py +133 -0
- dataops_sdk/tiptap/markdown_parser.py +294 -0
- dataops_sdk/tiptap/models.py +43 -0
- dataops_sdk/tiptap/parse_utils.py +889 -0
- dataops_sdk/tiptap/render_utils.py +846 -0
- dataops_sdk/tiptap/renderers.py +51 -0
- dataops_sdk/tiptap/tool.py +629 -0
- dataops_sdk/utils/__init__.py +15 -0
- dataops_sdk/utils/common.py +211 -0
- dataops_sdk/utils/utils.py +120 -0
- dataops_sdk-0.3.0.dist-info/METADATA +25 -0
- dataops_sdk-0.3.0.dist-info/RECORD +79 -0
- dataops_sdk-0.3.0.dist-info/WHEEL +5 -0
- dataops_sdk-0.3.0.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,243 @@
|
|
|
1
|
+
"""
|
|
2
|
+
基于 SFTP 的文件传输实现。
|
|
3
|
+
|
|
4
|
+
继承自 FileTransferBase,使用 paramiko 实现 SFTP 文件传输。
|
|
5
|
+
需要安装 paramiko 依赖:pip install paramiko>=3.0.0
|
|
6
|
+
|
|
7
|
+
Classes:
|
|
8
|
+
SFTPFileTransfer: 基于 paramiko 的 SFTP 文件传输类
|
|
9
|
+
|
|
10
|
+
Example:
|
|
11
|
+
>>> # 使用密码认证
|
|
12
|
+
>>> with SFTPFileTransfer(host="sftp.example.com", port=22,
|
|
13
|
+
... user="sftp_user", password="sftp_password",
|
|
14
|
+
... remote_path="/uploads") as sftp:
|
|
15
|
+
... sftp.upload("/local/file.txt", "remote_file.txt")
|
|
16
|
+
... files = sftp.list_files("*.txt")
|
|
17
|
+
...
|
|
18
|
+
>>> # 使用 SSH 密钥认证(password=None)
|
|
19
|
+
>>> with SFTPFileTransfer(host="sftp.example.com", port=22,
|
|
20
|
+
... user="sftp_user", password=None,
|
|
21
|
+
... remote_path="/uploads") as sftp:
|
|
22
|
+
... sftp.upload("/local/file.txt", "remote_file.txt")
|
|
23
|
+
"""
|
|
24
|
+
|
|
25
|
+
import fnmatch
|
|
26
|
+
from io import BytesIO
|
|
27
|
+
from pathlib import Path
|
|
28
|
+
from typing import BinaryIO
|
|
29
|
+
|
|
30
|
+
import paramiko
|
|
31
|
+
|
|
32
|
+
from .file_transfer_base import FileTransferBase
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
class SFTPFileTransfer(FileTransferBase):
|
|
36
|
+
"""
|
|
37
|
+
基于 paramiko 的 SFTP 文件传输类。
|
|
38
|
+
|
|
39
|
+
支持:
|
|
40
|
+
- 上传/下载文件(支持 SSH 密钥认证)
|
|
41
|
+
- 列出远程文件(支持 glob 模式过滤)
|
|
42
|
+
- 删除远程文件
|
|
43
|
+
- 检查文件是否存在
|
|
44
|
+
- 连接健康检查
|
|
45
|
+
- 上下文管理器(自动关闭连接)
|
|
46
|
+
|
|
47
|
+
继承自 FileTransferBase,实现所有抽象方法。
|
|
48
|
+
|
|
49
|
+
Attributes:
|
|
50
|
+
_ssh: paramiko.SSHClient 实例
|
|
51
|
+
_sftp: paramiko.SFTPClient 实例
|
|
52
|
+
|
|
53
|
+
Example:
|
|
54
|
+
>>> # 使用密码认证
|
|
55
|
+
>>> with SFTPFileTransfer(host="sftp.example.com", port=22,
|
|
56
|
+
... user="sftp_user", password="sftp_password",
|
|
57
|
+
... remote_path="/uploads") as sftp:
|
|
58
|
+
... sftp.upload("/local/file.txt", "remote_file.txt")
|
|
59
|
+
... files = sftp.list_files("*.txt")
|
|
60
|
+
...
|
|
61
|
+
>>> # 使用 SSH 密钥认证
|
|
62
|
+
>>> with SFTPFileTransfer(host="sftp.example.com", port=22,
|
|
63
|
+
... user="sftp_user", password=None,
|
|
64
|
+
... remote_path="/uploads") as sftp:
|
|
65
|
+
... sftp.upload("/local/file.txt", "remote_file.txt")
|
|
66
|
+
"""
|
|
67
|
+
|
|
68
|
+
def post_init(self):
|
|
69
|
+
"""
|
|
70
|
+
初始化 SFTP 连接。
|
|
71
|
+
|
|
72
|
+
连接到 SFTP 服务器并切换到远程基础目录。
|
|
73
|
+
支持密码认证和 SSH 密钥认证(password=None 时使用默认 SSH 密钥)。
|
|
74
|
+
|
|
75
|
+
Returns:
|
|
76
|
+
None
|
|
77
|
+
"""
|
|
78
|
+
self.logger.info(f"Connecting to SFTP server: {self._host}:{self._port}")
|
|
79
|
+
|
|
80
|
+
self._ssh: paramiko.SSHClient = paramiko.SSHClient()
|
|
81
|
+
self._ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
|
|
82
|
+
|
|
83
|
+
# 连接认证
|
|
84
|
+
if self._password:
|
|
85
|
+
self._ssh.connect(
|
|
86
|
+
hostname=self._host,
|
|
87
|
+
port=self._port,
|
|
88
|
+
username=self._user,
|
|
89
|
+
password=self._password,
|
|
90
|
+
)
|
|
91
|
+
else:
|
|
92
|
+
# 尝试使用默认 SSH 密钥
|
|
93
|
+
self._ssh.connect(
|
|
94
|
+
hostname=self._host,
|
|
95
|
+
port=self._port,
|
|
96
|
+
username=self._user,
|
|
97
|
+
)
|
|
98
|
+
|
|
99
|
+
self._sftp = self._ssh.open_sftp()
|
|
100
|
+
|
|
101
|
+
# 切换到远程基础目录
|
|
102
|
+
self._sftp.chdir(self._remote_path)
|
|
103
|
+
|
|
104
|
+
self.logger.info(f"SFTP connection established to {self._host}")
|
|
105
|
+
|
|
106
|
+
def upload(self, fp: BinaryIO | str | bytes, remote_name: str) -> bool:
|
|
107
|
+
"""
|
|
108
|
+
上传文件到 SFTP 服务器。
|
|
109
|
+
|
|
110
|
+
Args:
|
|
111
|
+
fp: 文件对象,支持任意 IO 类型(如 BytesIO, FileIO 等)。
|
|
112
|
+
remote_name: 远程文件名。
|
|
113
|
+
|
|
114
|
+
Returns:
|
|
115
|
+
bool: 上传成功返回 True,否则返回 False。
|
|
116
|
+
"""
|
|
117
|
+
try:
|
|
118
|
+
if isinstance(fp, str):
|
|
119
|
+
fp = BytesIO(fp.encode("utf-8"))
|
|
120
|
+
elif isinstance(fp, bytes):
|
|
121
|
+
fp = BytesIO(fp)
|
|
122
|
+
self._sftp.putfo(fp, remote_name)
|
|
123
|
+
self.logger.info(f"Uploaded: -> {remote_name}")
|
|
124
|
+
return True
|
|
125
|
+
except Exception as e:
|
|
126
|
+
self.logger.error(f"Failed to upload: {e}")
|
|
127
|
+
return False
|
|
128
|
+
|
|
129
|
+
def download(self, remote_name: str, local_path: str) -> bool:
|
|
130
|
+
"""
|
|
131
|
+
从 SFTP 服务器下载文件。
|
|
132
|
+
|
|
133
|
+
Args:
|
|
134
|
+
remote_name: 远程文件名。
|
|
135
|
+
local_path: 本地保存路径。
|
|
136
|
+
|
|
137
|
+
Returns:
|
|
138
|
+
bool: 下载成功返回 True,否则返回 False。
|
|
139
|
+
"""
|
|
140
|
+
try:
|
|
141
|
+
# 确保本地目录存在
|
|
142
|
+
Path(local_path).parent.mkdir(parents=True, exist_ok=True)
|
|
143
|
+
|
|
144
|
+
self._sftp.get(remote_name, local_path)
|
|
145
|
+
self.logger.info(f"Downloaded: {remote_name} -> {local_path}")
|
|
146
|
+
return True
|
|
147
|
+
except Exception as e:
|
|
148
|
+
self.logger.error(f"Failed to download {remote_name}: {e}")
|
|
149
|
+
return False
|
|
150
|
+
|
|
151
|
+
def list_files(self, pattern: str | None = None) -> list[str]:
|
|
152
|
+
"""
|
|
153
|
+
列出 SFTP 远程目录下的文件。
|
|
154
|
+
|
|
155
|
+
Args:
|
|
156
|
+
pattern: 可选的 glob 模式,用于过滤文件名。
|
|
157
|
+
|
|
158
|
+
Returns:
|
|
159
|
+
list[str]: 文件名列表。
|
|
160
|
+
"""
|
|
161
|
+
try:
|
|
162
|
+
files = self._sftp.listdir()
|
|
163
|
+
if pattern:
|
|
164
|
+
files = [f for f in files if fnmatch.fnmatch(f, pattern)]
|
|
165
|
+
return files
|
|
166
|
+
except Exception as e:
|
|
167
|
+
self.logger.error(f"Failed to list files: {e}")
|
|
168
|
+
return []
|
|
169
|
+
|
|
170
|
+
def delete(self, remote_name: str) -> bool:
|
|
171
|
+
"""
|
|
172
|
+
删除 SFTP 服务器上的文件。
|
|
173
|
+
|
|
174
|
+
Args:
|
|
175
|
+
remote_name: 远程文件名。
|
|
176
|
+
|
|
177
|
+
Returns:
|
|
178
|
+
bool: 删除成功返回 True,否则返回 False。
|
|
179
|
+
"""
|
|
180
|
+
try:
|
|
181
|
+
self._sftp.remove(remote_name)
|
|
182
|
+
self.logger.info(f"Deleted: {remote_name}")
|
|
183
|
+
return True
|
|
184
|
+
except Exception as e:
|
|
185
|
+
self.logger.error(f"Failed to delete {remote_name}: {e}")
|
|
186
|
+
return False
|
|
187
|
+
|
|
188
|
+
def exists(self, remote_name: str) -> bool:
|
|
189
|
+
"""
|
|
190
|
+
检查 SFTP 服务器上文件是否存在。
|
|
191
|
+
|
|
192
|
+
Args:
|
|
193
|
+
remote_name: 远程文件名。
|
|
194
|
+
|
|
195
|
+
Returns:
|
|
196
|
+
bool: 文件存在返回 True,否则返回 False。
|
|
197
|
+
"""
|
|
198
|
+
try:
|
|
199
|
+
self._sftp.stat(remote_name)
|
|
200
|
+
return True
|
|
201
|
+
except FileNotFoundError:
|
|
202
|
+
return False
|
|
203
|
+
except Exception as e:
|
|
204
|
+
self.logger.error(f"Failed to check existence of {remote_name}: {e}")
|
|
205
|
+
return False
|
|
206
|
+
|
|
207
|
+
def ping(self) -> bool:
|
|
208
|
+
"""
|
|
209
|
+
检查 SFTP 连接是否存活。
|
|
210
|
+
|
|
211
|
+
Returns:
|
|
212
|
+
bool: 连接正常返回 True,否则返回 False。
|
|
213
|
+
"""
|
|
214
|
+
try:
|
|
215
|
+
# 执行一个简单的 SFTP 操作来检查连接
|
|
216
|
+
channel = self._sftp.get_channel()
|
|
217
|
+
return channel is not None and not channel.closed
|
|
218
|
+
except Exception as e:
|
|
219
|
+
self.logger.warning(f"SFTP ping failed: {e}")
|
|
220
|
+
return False
|
|
221
|
+
|
|
222
|
+
def close(self):
|
|
223
|
+
"""
|
|
224
|
+
关闭 SFTP 连接。
|
|
225
|
+
|
|
226
|
+
关闭 SFTP 和 SSH 连接,释放资源。
|
|
227
|
+
支持多次调用。
|
|
228
|
+
"""
|
|
229
|
+
if hasattr(self, "_sftp") and self._sftp is not None:
|
|
230
|
+
try:
|
|
231
|
+
self._sftp.close()
|
|
232
|
+
self.logger.info("SFTP channel closed")
|
|
233
|
+
except Exception as e:
|
|
234
|
+
self.logger.error(f"Failed to close SFTP channel: {e}")
|
|
235
|
+
self._sftp = None
|
|
236
|
+
|
|
237
|
+
if hasattr(self, "_ssh") and self._ssh is not None:
|
|
238
|
+
try:
|
|
239
|
+
self._ssh.close()
|
|
240
|
+
self.logger.info("SSH connection closed")
|
|
241
|
+
except Exception as e:
|
|
242
|
+
self.logger.error(f"Failed to close SSH connection: {e}")
|
|
243
|
+
self._ssh = None
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
from .alarm import AlarmRuleItem
|
|
2
|
+
from .api import ApiMeta, HttpInterfaceData
|
|
3
|
+
from .data_table import DataTableData, MetaDataTable
|
|
4
|
+
from .datasource import DataDataSource
|
|
5
|
+
from .dict_ import DataDict, DictItem
|
|
6
|
+
from .enums import InnerMetaType, MetaType
|
|
7
|
+
from .group import GroupNode
|
|
8
|
+
from .hazard import HazardRecordDTO, HazardTaskDTO
|
|
9
|
+
from .meta import (
|
|
10
|
+
DEFAULT_META_DATA_TYPE,
|
|
11
|
+
META_DATA_TYPE,
|
|
12
|
+
Meta,
|
|
13
|
+
MetaBase,
|
|
14
|
+
MetaCreate,
|
|
15
|
+
MetaRef,
|
|
16
|
+
MetaRelease,
|
|
17
|
+
MetaUpdate,
|
|
18
|
+
)
|
|
19
|
+
from .query import PageParam, SqlCondition, SqlQueryParam, SqlSort
|
|
20
|
+
from .report import ReportMeta, ReportMetaData
|
|
21
|
+
from .skill import DataSkill, MetaSkill, SkillCallResult
|
|
22
|
+
from .table import (
|
|
23
|
+
ColumnItem,
|
|
24
|
+
DataBaseColumnDictExternal,
|
|
25
|
+
DataBaseColumnReference,
|
|
26
|
+
DataBaseColumnReferenceValue,
|
|
27
|
+
DataBaseColumnTableExternal,
|
|
28
|
+
DataDataBase,
|
|
29
|
+
)
|
|
30
|
+
from .user import Application, UserInfo
|
|
31
|
+
from .widget import WidgetMeta, WidgetMetaData
|
|
32
|
+
from .workflow import DataWorkflow, MetaWorkflow
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
from typing import Annotated
|
|
2
|
+
|
|
3
|
+
from pydantic import BaseModel, Field
|
|
4
|
+
|
|
5
|
+
from dataops_sdk.schemas.meta import MetaRelease
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class AlarmExternal(BaseModel):
|
|
9
|
+
IS_ENABLED: Annotated[str, Field(description="是否启用")]
|
|
10
|
+
N_IS_ENABLED: Annotated[str, Field(description="是否启用名称")]
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
class AlarmRuleItem(MetaRelease, AlarmExternal):
|
|
14
|
+
INDUSTRY: Annotated[str, Field(description="行业")]
|
|
15
|
+
DESCRIPTION: Annotated[str, Field(description="描述")] = ""
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
class AlarmSpecItem(MetaRelease, AlarmExternal):
|
|
19
|
+
INDUSTRY: Annotated[str, Field(description="行业")]
|
|
20
|
+
N_INDUSTRY: Annotated[str, Field(description="行业名称")]
|
|
21
|
+
BUSINESS_DOMAIN: Annotated[str, Field(description="业务域")]
|
|
22
|
+
N_BUSINESS_DOMAIN: Annotated[str, Field(description="业务域名称")]
|
|
23
|
+
KAFKA_TOPICS: Annotated[str, Field(description="Kafka主题列表")]
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
class AlarmActionItem(MetaRelease, AlarmExternal):
|
|
27
|
+
RULE_TYPE: Annotated[str, Field(description="规则类型")]
|
|
28
|
+
N_RULE_TYPE: Annotated[str, Field(description="规则类型名称")]
|
|
29
|
+
|
|
30
|
+
SCRIPT_CONTENT: Annotated[str, Field(description="脚本内容")]
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
class AlarmRuleMatchItem(MetaRelease, AlarmExternal):
|
|
34
|
+
AREA: Annotated[str, Field(description="区域")]
|
|
35
|
+
SPEC_TYPE: Annotated[str, Field(description="规则类型")]
|
|
36
|
+
N_SPEC_TYPE: Annotated[str, Field(description="规则类型名称")]
|
|
37
|
+
RULE_TYPE: Annotated[str, Field(description="规则类型")]
|
|
38
|
+
N_RULE_TYPE: Annotated[str, Field(description="规则类型名称")]
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
from collections.abc import Mapping
|
|
2
|
+
from typing import Annotated
|
|
3
|
+
|
|
4
|
+
from pydantic import BaseModel, Field, JsonValue
|
|
5
|
+
|
|
6
|
+
from .meta import Meta
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
class HttpInterfaceData(BaseModel):
|
|
10
|
+
"""API 接口元数据.
|
|
11
|
+
|
|
12
|
+
对应前端 types/restful.ts 中的 HttpInterface 类型。
|
|
13
|
+
"""
|
|
14
|
+
|
|
15
|
+
endpoint: Annotated[str, Field(description="接口路径")]
|
|
16
|
+
method: Annotated[str, Field(description="HTTP 方法: GET/POST/PUT/DELETE/PATCH/HEAD/OPTIONS")]
|
|
17
|
+
status: Annotated[str, Field(description="接口状态: dev/test/prod/deprecated")]
|
|
18
|
+
scope: Annotated[str, Field(description="接口范围: public/internal/external")]
|
|
19
|
+
description: Annotated[str, Field(description="接口说明,支持 Markdown")] = ""
|
|
20
|
+
charger: Annotated[str | None, Field(description="负责人")] = None
|
|
21
|
+
env_code: Annotated[str | None, Field(description="关联环境编码")] = None
|
|
22
|
+
requestParam: Annotated[
|
|
23
|
+
Mapping[str, JsonValue],
|
|
24
|
+
Field(description="请求参数(query/path/body/headers/cookies/auth)"),
|
|
25
|
+
]
|
|
26
|
+
responseParams: Annotated[
|
|
27
|
+
list[Mapping[str, JsonValue]], Field(description="响应参数定义", default_factory=list)
|
|
28
|
+
]
|
|
29
|
+
response: Annotated[Mapping[str, JsonValue] | None, Field(description="调试响应快照")] = None
|
|
30
|
+
debugExamples: Annotated[
|
|
31
|
+
list[Mapping[str, JsonValue]] | None,
|
|
32
|
+
Field(description="调试测试用例", default_factory=list),
|
|
33
|
+
]
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
class ApiMeta(Meta[HttpInterfaceData]):
|
|
37
|
+
"""API Meta"""
|