dataops-sdk 0.3.0__tar.gz → 0.3.1__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.
- {dataops_sdk-0.3.0 → dataops_sdk-0.3.1}/PKG-INFO +1 -1
- {dataops_sdk-0.3.0 → dataops_sdk-0.3.1}/src/dataops_sdk/__init__.py +9 -1
- {dataops_sdk-0.3.0 → dataops_sdk-0.3.1}/src/dataops_sdk/runner/utils/common.py +2 -1
- {dataops_sdk-0.3.0 → dataops_sdk-0.3.1}/src/dataops_sdk/runner/utils/dbConn_sync.py +7 -8
- {dataops_sdk-0.3.0 → dataops_sdk-0.3.1}/src/dataops_sdk/runner/utils/file_transfer_base.py +0 -1
- {dataops_sdk-0.3.0 → dataops_sdk-0.3.1}/src/dataops_sdk/runner/utils/nacos.py +4 -1
- {dataops_sdk-0.3.0 → dataops_sdk-0.3.1}/src/dataops_sdk/runner/utils/queue_base.py +0 -1
- {dataops_sdk-0.3.0 → dataops_sdk-0.3.1}/src/dataops_sdk/schemas/datasource.py +2 -1
- {dataops_sdk-0.3.0 → dataops_sdk-0.3.1}/src/dataops_sdk/services/__init__.py +4 -4
- {dataops_sdk-0.3.0 → dataops_sdk-0.3.1}/src/dataops_sdk/services/datasource.py +11 -4
- {dataops_sdk-0.3.0 → dataops_sdk-0.3.1}/src/dataops_sdk/services/skill.py +15 -9
- {dataops_sdk-0.3.0 → dataops_sdk-0.3.1}/src/dataops_sdk/session.py +108 -5
- {dataops_sdk-0.3.0 → dataops_sdk-0.3.1}/src/dataops_sdk/tiptap/markdown_parser.py +6 -2
- {dataops_sdk-0.3.0 → dataops_sdk-0.3.1}/src/dataops_sdk.egg-info/PKG-INFO +1 -1
- {dataops_sdk-0.3.0 → dataops_sdk-0.3.1}/tests/test_session.py +4 -6
- {dataops_sdk-0.3.0 → dataops_sdk-0.3.1}/tests/test_utils.py +3 -5
- {dataops_sdk-0.3.0 → dataops_sdk-0.3.1}/pyproject.toml +0 -0
- {dataops_sdk-0.3.0 → dataops_sdk-0.3.1}/setup.cfg +0 -0
- {dataops_sdk-0.3.0 → dataops_sdk-0.3.1}/src/dataops_sdk/constants.py +0 -0
- {dataops_sdk-0.3.0 → dataops_sdk-0.3.1}/src/dataops_sdk/exceptions.py +0 -0
- {dataops_sdk-0.3.0 → dataops_sdk-0.3.1}/src/dataops_sdk/runner/__init__.py +0 -0
- {dataops_sdk-0.3.0 → dataops_sdk-0.3.1}/src/dataops_sdk/runner/datasource_factory.py +0 -0
- {dataops_sdk-0.3.0 → dataops_sdk-0.3.1}/src/dataops_sdk/runner/schemas/nacos/__init__.py +0 -0
- {dataops_sdk-0.3.0 → dataops_sdk-0.3.1}/src/dataops_sdk/runner/schemas/nacos/config.py +0 -0
- {dataops_sdk-0.3.0 → dataops_sdk-0.3.1}/src/dataops_sdk/runner/schemas/nacos/constants.py +0 -0
- {dataops_sdk-0.3.0 → dataops_sdk-0.3.1}/src/dataops_sdk/runner/schemas/nacos/instance.py +0 -0
- {dataops_sdk-0.3.0 → dataops_sdk-0.3.1}/src/dataops_sdk/runner/schemas/nacos/nacos_exception.py +0 -0
- {dataops_sdk-0.3.0 → dataops_sdk-0.3.1}/src/dataops_sdk/runner/schemas/nacos/naming_param.py +0 -0
- {dataops_sdk-0.3.0 → dataops_sdk-0.3.1}/src/dataops_sdk/runner/schemas/nacos/naming_request.py +0 -0
- {dataops_sdk-0.3.0 → dataops_sdk-0.3.1}/src/dataops_sdk/runner/schemas/nacos/naming_response.py +0 -0
- {dataops_sdk-0.3.0 → dataops_sdk-0.3.1}/src/dataops_sdk/runner/schemas/nacos/preserved_metadata_key.py +0 -0
- {dataops_sdk-0.3.0 → dataops_sdk-0.3.1}/src/dataops_sdk/runner/schemas/nacos/service.py +0 -0
- {dataops_sdk-0.3.0 → dataops_sdk-0.3.1}/src/dataops_sdk/runner/utils/__init__.py +0 -0
- {dataops_sdk-0.3.0 → dataops_sdk-0.3.1}/src/dataops_sdk/runner/utils/dbConn_base.py +0 -0
- {dataops_sdk-0.3.0 → dataops_sdk-0.3.1}/src/dataops_sdk/runner/utils/duckdb_manager.py +0 -0
- {dataops_sdk-0.3.0 → dataops_sdk-0.3.1}/src/dataops_sdk/runner/utils/ftp_file_transfer.py +0 -0
- {dataops_sdk-0.3.0 → dataops_sdk-0.3.1}/src/dataops_sdk/runner/utils/log.py +0 -0
- {dataops_sdk-0.3.0 → dataops_sdk-0.3.1}/src/dataops_sdk/runner/utils/neo4j_sync.py +0 -0
- {dataops_sdk-0.3.0 → dataops_sdk-0.3.1}/src/dataops_sdk/runner/utils/queue_kafka.py +0 -0
- {dataops_sdk-0.3.0 → dataops_sdk-0.3.1}/src/dataops_sdk/runner/utils/sftp_file_transfer.py +0 -0
- {dataops_sdk-0.3.0 → dataops_sdk-0.3.1}/src/dataops_sdk/schemas/__init__.py +0 -0
- {dataops_sdk-0.3.0 → dataops_sdk-0.3.1}/src/dataops_sdk/schemas/alarm.py +0 -0
- {dataops_sdk-0.3.0 → dataops_sdk-0.3.1}/src/dataops_sdk/schemas/api.py +0 -0
- {dataops_sdk-0.3.0 → dataops_sdk-0.3.1}/src/dataops_sdk/schemas/data_table.py +0 -0
- {dataops_sdk-0.3.0 → dataops_sdk-0.3.1}/src/dataops_sdk/schemas/dict_.py +0 -0
- {dataops_sdk-0.3.0 → dataops_sdk-0.3.1}/src/dataops_sdk/schemas/enums.py +0 -0
- {dataops_sdk-0.3.0 → dataops_sdk-0.3.1}/src/dataops_sdk/schemas/group.py +0 -0
- {dataops_sdk-0.3.0 → dataops_sdk-0.3.1}/src/dataops_sdk/schemas/hazard.py +0 -0
- {dataops_sdk-0.3.0 → dataops_sdk-0.3.1}/src/dataops_sdk/schemas/meta.py +0 -0
- {dataops_sdk-0.3.0 → dataops_sdk-0.3.1}/src/dataops_sdk/schemas/query.py +0 -0
- {dataops_sdk-0.3.0 → dataops_sdk-0.3.1}/src/dataops_sdk/schemas/report.py +0 -0
- {dataops_sdk-0.3.0 → dataops_sdk-0.3.1}/src/dataops_sdk/schemas/skill.py +0 -0
- {dataops_sdk-0.3.0 → dataops_sdk-0.3.1}/src/dataops_sdk/schemas/table.py +0 -0
- {dataops_sdk-0.3.0 → dataops_sdk-0.3.1}/src/dataops_sdk/schemas/user.py +0 -0
- {dataops_sdk-0.3.0 → dataops_sdk-0.3.1}/src/dataops_sdk/schemas/widget.py +0 -0
- {dataops_sdk-0.3.0 → dataops_sdk-0.3.1}/src/dataops_sdk/schemas/workflow.py +0 -0
- {dataops_sdk-0.3.0 → dataops_sdk-0.3.1}/src/dataops_sdk/services/alarm.py +0 -0
- {dataops_sdk-0.3.0 → dataops_sdk-0.3.1}/src/dataops_sdk/services/api.py +0 -0
- {dataops_sdk-0.3.0 → dataops_sdk-0.3.1}/src/dataops_sdk/services/auth.py +0 -0
- {dataops_sdk-0.3.0 → dataops_sdk-0.3.1}/src/dataops_sdk/services/data_table.py +0 -0
- {dataops_sdk-0.3.0 → dataops_sdk-0.3.1}/src/dataops_sdk/services/dataset.py +0 -0
- {dataops_sdk-0.3.0 → dataops_sdk-0.3.1}/src/dataops_sdk/services/dict_.py +0 -0
- {dataops_sdk-0.3.0 → dataops_sdk-0.3.1}/src/dataops_sdk/services/hazard.py +0 -0
- {dataops_sdk-0.3.0 → dataops_sdk-0.3.1}/src/dataops_sdk/services/meta.py +0 -0
- {dataops_sdk-0.3.0 → dataops_sdk-0.3.1}/src/dataops_sdk/services/metrics.py +0 -0
- {dataops_sdk-0.3.0 → dataops_sdk-0.3.1}/src/dataops_sdk/services/ref.py +0 -0
- {dataops_sdk-0.3.0 → dataops_sdk-0.3.1}/src/dataops_sdk/services/report.py +0 -0
- {dataops_sdk-0.3.0 → dataops_sdk-0.3.1}/src/dataops_sdk/services/table.py +0 -0
- {dataops_sdk-0.3.0 → dataops_sdk-0.3.1}/src/dataops_sdk/services/widget.py +0 -0
- {dataops_sdk-0.3.0 → dataops_sdk-0.3.1}/src/dataops_sdk/services/workflow.py +0 -0
- {dataops_sdk-0.3.0 → dataops_sdk-0.3.1}/src/dataops_sdk/tiptap/__init__.py +0 -0
- {dataops_sdk-0.3.0 → dataops_sdk-0.3.1}/src/dataops_sdk/tiptap/builder.py +0 -0
- {dataops_sdk-0.3.0 → dataops_sdk-0.3.1}/src/dataops_sdk/tiptap/constants.py +0 -0
- {dataops_sdk-0.3.0 → dataops_sdk-0.3.1}/src/dataops_sdk/tiptap/models.py +0 -0
- {dataops_sdk-0.3.0 → dataops_sdk-0.3.1}/src/dataops_sdk/tiptap/parse_utils.py +0 -0
- {dataops_sdk-0.3.0 → dataops_sdk-0.3.1}/src/dataops_sdk/tiptap/render_utils.py +0 -0
- {dataops_sdk-0.3.0 → dataops_sdk-0.3.1}/src/dataops_sdk/tiptap/renderers.py +0 -0
- {dataops_sdk-0.3.0 → dataops_sdk-0.3.1}/src/dataops_sdk/tiptap/tool.py +0 -0
- {dataops_sdk-0.3.0 → dataops_sdk-0.3.1}/src/dataops_sdk/utils/__init__.py +0 -0
- {dataops_sdk-0.3.0 → dataops_sdk-0.3.1}/src/dataops_sdk/utils/common.py +0 -0
- {dataops_sdk-0.3.0 → dataops_sdk-0.3.1}/src/dataops_sdk/utils/utils.py +0 -0
- {dataops_sdk-0.3.0 → dataops_sdk-0.3.1}/src/dataops_sdk.egg-info/SOURCES.txt +0 -0
- {dataops_sdk-0.3.0 → dataops_sdk-0.3.1}/src/dataops_sdk.egg-info/dependency_links.txt +0 -0
- {dataops_sdk-0.3.0 → dataops_sdk-0.3.1}/src/dataops_sdk.egg-info/requires.txt +0 -0
- {dataops_sdk-0.3.0 → dataops_sdk-0.3.1}/src/dataops_sdk.egg-info/top_level.txt +0 -0
- {dataops_sdk-0.3.0 → dataops_sdk-0.3.1}/tests/test_constants.py +0 -0
- {dataops_sdk-0.3.0 → dataops_sdk-0.3.1}/tests/test_exceptions.py +0 -0
|
@@ -14,6 +14,7 @@ from .services import ( # noqa: F401
|
|
|
14
14
|
service_count_alarm_rule_matches,
|
|
15
15
|
service_count_alarm_rules,
|
|
16
16
|
service_count_alarm_specs,
|
|
17
|
+
service_count_dataset_by_code,
|
|
17
18
|
service_count_table_by_code,
|
|
18
19
|
service_count_table_by_name,
|
|
19
20
|
service_count_widget_by_code,
|
|
@@ -48,6 +49,8 @@ from .services import ( # noqa: F401
|
|
|
48
49
|
service_get_metrics,
|
|
49
50
|
service_get_rel_table_columns,
|
|
50
51
|
service_get_report,
|
|
52
|
+
service_get_skill_by_code,
|
|
53
|
+
service_get_skill_by_name,
|
|
51
54
|
service_get_table_data_by_code,
|
|
52
55
|
service_get_table_data_by_name,
|
|
53
56
|
service_get_table_detail_by_code,
|
|
@@ -66,6 +69,8 @@ from .services import ( # noqa: F401
|
|
|
66
69
|
service_list_hazard_records,
|
|
67
70
|
service_list_metrics,
|
|
68
71
|
service_list_reports,
|
|
72
|
+
service_list_skill_files,
|
|
73
|
+
service_list_skills,
|
|
69
74
|
service_list_tables,
|
|
70
75
|
service_list_widgets,
|
|
71
76
|
service_list_workflows,
|
|
@@ -74,6 +79,9 @@ from .services import ( # noqa: F401
|
|
|
74
79
|
service_ref_backward,
|
|
75
80
|
service_ref_forward,
|
|
76
81
|
service_set_application,
|
|
82
|
+
service_skill_call_by_code,
|
|
83
|
+
service_skill_import,
|
|
84
|
+
service_skill_upload_sub_file,
|
|
77
85
|
service_start_workflow,
|
|
78
86
|
service_start_workflow_async,
|
|
79
87
|
service_trigger_hazard_task,
|
|
@@ -81,4 +89,4 @@ from .services import ( # noqa: F401
|
|
|
81
89
|
service_update_data_table_record_by_id_list,
|
|
82
90
|
)
|
|
83
91
|
|
|
84
|
-
__version__ = "0.3.
|
|
92
|
+
__version__ = "0.3.1"
|
|
@@ -17,9 +17,10 @@ Example:
|
|
|
17
17
|
|
|
18
18
|
from base64 import b64decode, b64encode
|
|
19
19
|
from calendar import monthrange
|
|
20
|
+
from collections.abc import Mapping
|
|
20
21
|
from datetime import date, datetime, timedelta
|
|
21
22
|
from email.utils import parsedate_to_datetime
|
|
22
|
-
from typing import Any, Literal
|
|
23
|
+
from typing import Any, Literal
|
|
23
24
|
from uuid import uuid4
|
|
24
25
|
|
|
25
26
|
from pydantic import BaseModel, JsonValue
|
|
@@ -286,8 +286,7 @@ class DatabaseConn(DatabaseConnBase):
|
|
|
286
286
|
mapping: Literal[True] = True,
|
|
287
287
|
*,
|
|
288
288
|
log_sql: bool | None = None,
|
|
289
|
-
) -> list[dict[str, Any]]:
|
|
290
|
-
...
|
|
289
|
+
) -> list[dict[str, Any]]: ...
|
|
291
290
|
|
|
292
291
|
@overload
|
|
293
292
|
def select(
|
|
@@ -298,8 +297,7 @@ class DatabaseConn(DatabaseConnBase):
|
|
|
298
297
|
mapping: Literal[False] = False,
|
|
299
298
|
*,
|
|
300
299
|
log_sql: bool | None = None,
|
|
301
|
-
) -> list[tuple[Any]]:
|
|
302
|
-
...
|
|
300
|
+
) -> list[tuple[Any]]: ...
|
|
303
301
|
|
|
304
302
|
def select(
|
|
305
303
|
self,
|
|
@@ -378,7 +376,7 @@ class DatabaseConn(DatabaseConnBase):
|
|
|
378
376
|
if hasattr(self, "_engine") and self._engine is not None:
|
|
379
377
|
self.engine.dispose()
|
|
380
378
|
self._engine = None
|
|
381
|
-
self._logger.info(
|
|
379
|
+
self._logger.info("closed")
|
|
382
380
|
|
|
383
381
|
@property
|
|
384
382
|
def session_factory(self):
|
|
@@ -398,21 +396,21 @@ class DatabaseConn(DatabaseConnBase):
|
|
|
398
396
|
"""
|
|
399
397
|
提交当前事务。
|
|
400
398
|
"""
|
|
401
|
-
self._logger.debug(
|
|
399
|
+
self._logger.debug("committing")
|
|
402
400
|
self.session.commit()
|
|
403
401
|
|
|
404
402
|
def rollback(self):
|
|
405
403
|
"""
|
|
406
404
|
回滚当前事务。
|
|
407
405
|
"""
|
|
408
|
-
self._logger.warning(
|
|
406
|
+
self._logger.warning("rolling back")
|
|
409
407
|
self.session.rollback()
|
|
410
408
|
|
|
411
409
|
def begin(self):
|
|
412
410
|
"""
|
|
413
411
|
开始一个新的事务。
|
|
414
412
|
"""
|
|
415
|
-
self._logger.debug(
|
|
413
|
+
self._logger.debug("beginning")
|
|
416
414
|
if self.session:
|
|
417
415
|
assert self._session is not None, "session not closed"
|
|
418
416
|
self._session = self.session_factory()
|
|
@@ -428,6 +426,7 @@ class DatabaseConn(DatabaseConnBase):
|
|
|
428
426
|
"""
|
|
429
427
|
return self._session
|
|
430
428
|
|
|
429
|
+
|
|
431
430
|
class DatabaseConnDataOps(DatabaseConn):
|
|
432
431
|
def __init__(self, datasource: str, log_sql: bool | None = None):
|
|
433
432
|
from dataops_sdk.services.meta import Meta, release_list_get_by_name
|
|
@@ -15,6 +15,7 @@ import random
|
|
|
15
15
|
from collections.abc import Mapping
|
|
16
16
|
|
|
17
17
|
import httpx2
|
|
18
|
+
|
|
18
19
|
from dataops_sdk.runner.schemas.nacos import NacosSettings, Service
|
|
19
20
|
from dataops_sdk.runner.schemas.nacos.constants import Constants
|
|
20
21
|
|
|
@@ -88,7 +89,9 @@ def get_service_instance(
|
|
|
88
89
|
|
|
89
90
|
instance = random.choice(service.hosts)
|
|
90
91
|
|
|
91
|
-
http_client = httpx2.Client(
|
|
92
|
+
http_client = httpx2.Client(
|
|
93
|
+
base_url=f"http://{instance.ip}:{instance.port}/{service_name}", headers=headers
|
|
94
|
+
)
|
|
92
95
|
|
|
93
96
|
# 主进程结束前执行 http_client.close()
|
|
94
97
|
atexit.register(http_client.close)
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
from typing import Annotated
|
|
2
2
|
|
|
3
|
-
from dataops_sdk.schemas.enums import DataSourceType
|
|
4
3
|
from pydantic import BaseModel, BeforeValidator, Field
|
|
5
4
|
|
|
5
|
+
from dataops_sdk.schemas.enums import DataSourceType
|
|
6
|
+
|
|
6
7
|
|
|
7
8
|
def str_to_number(v: str):
|
|
8
9
|
assert v.isnumeric(), "must be number"
|
|
@@ -75,15 +75,15 @@ from .metrics import service_get_metrics, service_list_metrics
|
|
|
75
75
|
from .ref import service_ref_backward, service_ref_forward
|
|
76
76
|
from .report import service_get_report, service_list_reports
|
|
77
77
|
from .skill import (
|
|
78
|
-
service_call_skill_by_code,
|
|
79
78
|
service_delete_skill,
|
|
80
|
-
service_delete_sub_file,
|
|
81
79
|
service_get_skill_by_code,
|
|
82
80
|
service_get_skill_by_name,
|
|
83
|
-
service_import_skill,
|
|
84
81
|
service_list_skill_files,
|
|
85
82
|
service_list_skills,
|
|
86
|
-
|
|
83
|
+
service_skill_call_by_code,
|
|
84
|
+
service_skill_delete_sub_file,
|
|
85
|
+
service_skill_import,
|
|
86
|
+
service_skill_upload_sub_file,
|
|
87
87
|
)
|
|
88
88
|
from .table import (
|
|
89
89
|
service_count_table_by_code,
|
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
from dataclasses import dataclass
|
|
2
2
|
|
|
3
|
+
from pydantic_core import to_json
|
|
4
|
+
|
|
3
5
|
from dataops_sdk.exceptions import AuthenticationError, DataOpsError
|
|
4
6
|
from dataops_sdk.schemas import DataDataSource, Meta
|
|
5
7
|
from dataops_sdk.schemas.enums import InnerMetaType
|
|
6
8
|
from dataops_sdk.services.meta import release_list_get_by_name
|
|
7
9
|
from dataops_sdk.session import get_application, get_session
|
|
8
10
|
from dataops_sdk.utils import encrypt_body
|
|
9
|
-
from pydantic_core import to_json
|
|
10
11
|
|
|
11
12
|
|
|
12
13
|
def service_get_datasource_config_by_application_id(
|
|
@@ -39,16 +40,22 @@ class DatasourceConfig:
|
|
|
39
40
|
hazard_write: Meta[DataDataSource]
|
|
40
41
|
|
|
41
42
|
|
|
42
|
-
def service_get_main_datasource_config_by_application(
|
|
43
|
+
def service_get_main_datasource_config_by_application(
|
|
44
|
+
app_id: str | None = None,
|
|
45
|
+
) -> DatasourceConfig:
|
|
43
46
|
if app_id is None:
|
|
44
47
|
application = get_application()
|
|
45
48
|
app_id = application.CUID
|
|
46
49
|
# 主数据源
|
|
47
50
|
datasource_main = service_get_datasource_config_by_application_id(prod_id=app_id)
|
|
48
51
|
# 隐患读数据源
|
|
49
|
-
datasource_hazard_read = service_get_datasource_config_by_application_id(
|
|
52
|
+
datasource_hazard_read = service_get_datasource_config_by_application_id(
|
|
53
|
+
prod_id=app_id, param_name="datasource_hazard_read"
|
|
54
|
+
)
|
|
50
55
|
# 隐患写数据源
|
|
51
|
-
datasource_hazard_write = service_get_datasource_config_by_application_id(
|
|
56
|
+
datasource_hazard_write = service_get_datasource_config_by_application_id(
|
|
57
|
+
prod_id=app_id, param_name="datasource_hazard_write"
|
|
58
|
+
)
|
|
52
59
|
return DatasourceConfig(datasource_main, datasource_hazard_read, datasource_hazard_write)
|
|
53
60
|
|
|
54
61
|
|
|
@@ -4,7 +4,13 @@ from pathlib import Path
|
|
|
4
4
|
from pydantic_core import to_json
|
|
5
5
|
|
|
6
6
|
from dataops_sdk.exceptions import AuthenticationError, DataOpsError
|
|
7
|
-
from dataops_sdk.schemas import
|
|
7
|
+
from dataops_sdk.schemas import (
|
|
8
|
+
DataSkill,
|
|
9
|
+
MetaRelease,
|
|
10
|
+
MetaSkill,
|
|
11
|
+
MetaType,
|
|
12
|
+
SkillCallResult,
|
|
13
|
+
)
|
|
8
14
|
from dataops_sdk.services.meta import (
|
|
9
15
|
release_list_get_by_code,
|
|
10
16
|
release_list_get_by_name,
|
|
@@ -14,15 +20,15 @@ from dataops_sdk.session import get_session, post_multipart
|
|
|
14
20
|
from dataops_sdk.utils import encrypt_body, filter_nodes_by_pattern
|
|
15
21
|
|
|
16
22
|
__all__ = [
|
|
17
|
-
"
|
|
23
|
+
"service_skill_call_by_code",
|
|
18
24
|
"service_delete_skill",
|
|
19
|
-
"
|
|
25
|
+
"service_skill_delete_sub_file",
|
|
20
26
|
"service_get_skill_by_code",
|
|
21
27
|
"service_get_skill_by_name",
|
|
22
|
-
"
|
|
28
|
+
"service_skill_import",
|
|
23
29
|
"service_list_skill_files",
|
|
24
30
|
"service_list_skills",
|
|
25
|
-
"
|
|
31
|
+
"service_skill_upload_sub_file",
|
|
26
32
|
]
|
|
27
33
|
|
|
28
34
|
|
|
@@ -125,7 +131,7 @@ def _post_skill(url: str, body: dict | None = None, *, params: dict | None = Non
|
|
|
125
131
|
raise AuthenticationError("认证失败,请先登录") from e
|
|
126
132
|
|
|
127
133
|
|
|
128
|
-
def
|
|
134
|
+
def service_skill_import(
|
|
129
135
|
file_path: str | Path,
|
|
130
136
|
sub_type: str = "llm",
|
|
131
137
|
name: str | None = None,
|
|
@@ -193,7 +199,7 @@ def service_delete_skill(name: str) -> dict:
|
|
|
193
199
|
return _post_skill(f"/data/skill/delete/{name}")
|
|
194
200
|
|
|
195
201
|
|
|
196
|
-
def
|
|
202
|
+
def service_skill_upload_sub_file(
|
|
197
203
|
skill_name: str,
|
|
198
204
|
file_path: str | Path,
|
|
199
205
|
path: str,
|
|
@@ -225,7 +231,7 @@ def service_upload_sub_file(
|
|
|
225
231
|
resp.json() # 仅校验响应
|
|
226
232
|
|
|
227
233
|
|
|
228
|
-
def
|
|
234
|
+
def service_skill_delete_sub_file(skill_name: str, path: str) -> None:
|
|
229
235
|
"""删除技能下的指定子文件.
|
|
230
236
|
|
|
231
237
|
Args:
|
|
@@ -239,7 +245,7 @@ def service_delete_sub_file(skill_name: str, path: str) -> None:
|
|
|
239
245
|
_post_skill(f"/data/skill/{skill_name}/subfile/delete", params={"path": path})
|
|
240
246
|
|
|
241
247
|
|
|
242
|
-
def
|
|
248
|
+
def service_skill_call_by_code(code: str, inputs: Mapping) -> SkillCallResult:
|
|
243
249
|
"""调用 skill 同步执行,返回 Python 容器运行结果.
|
|
244
250
|
|
|
245
251
|
对应后端 ``POST /data/skill/callByCode/{code}``,入参 ``{"inputs": {...}}``。
|
|
@@ -1,16 +1,40 @@
|
|
|
1
1
|
import os
|
|
2
2
|
from collections.abc import Mapping
|
|
3
3
|
from contextlib import contextmanager
|
|
4
|
+
from contextvars import ContextVar
|
|
4
5
|
from os import getenv
|
|
5
6
|
from typing import IO, BinaryIO
|
|
6
7
|
|
|
7
8
|
import httpx2
|
|
9
|
+
from pydantic import BaseModel
|
|
10
|
+
from pydantic_core import from_json, to_json
|
|
11
|
+
|
|
8
12
|
from dataops_sdk.constants import APPLICATION_FILE, USER_INFO_FILE
|
|
9
13
|
from dataops_sdk.exceptions import AuthenticationError, DataOpsError
|
|
10
14
|
from dataops_sdk.schemas.user import Application, UserInfo
|
|
11
15
|
from dataops_sdk.utils import get_work_dir
|
|
12
|
-
|
|
13
|
-
|
|
16
|
+
|
|
17
|
+
__all__ = [
|
|
18
|
+
"DataOpsConfig",
|
|
19
|
+
"configure",
|
|
20
|
+
"get_config",
|
|
21
|
+
"set_request_auth",
|
|
22
|
+
"clear_request_auth",
|
|
23
|
+
"request_context",
|
|
24
|
+
"get_user_info_file_path",
|
|
25
|
+
"get_application_file_path",
|
|
26
|
+
"get_user_info",
|
|
27
|
+
"get_headers",
|
|
28
|
+
"refresh_token",
|
|
29
|
+
"get_application",
|
|
30
|
+
"get_session",
|
|
31
|
+
"post_multipart",
|
|
32
|
+
]
|
|
33
|
+
|
|
34
|
+
# Request-scoped auth headers context variable
|
|
35
|
+
# 默认 None,表示使用模块级认证(环境变量/file/config)
|
|
36
|
+
# 在 FastAPI/异步环境中,每个 async task 有独立的副本,互不干扰
|
|
37
|
+
REQUEST_HEADERS: ContextVar[dict[str, str] | None] = ContextVar("REQUEST_HEADERS", default=None)
|
|
14
38
|
|
|
15
39
|
|
|
16
40
|
class DataOpsConfig(BaseModel):
|
|
@@ -81,6 +105,59 @@ def get_config() -> DataOpsConfig:
|
|
|
81
105
|
return _config
|
|
82
106
|
|
|
83
107
|
|
|
108
|
+
def set_request_auth(headers: dict[str, str]) -> None:
|
|
109
|
+
"""设置本次请求的认证头。
|
|
110
|
+
|
|
111
|
+
在 FastAPI 请求处理器开头调用,后续 SDK 调用会使用此认证信息。
|
|
112
|
+
每个 async task 有独立的上下文副本,支持并发请求。
|
|
113
|
+
|
|
114
|
+
Args:
|
|
115
|
+
headers: 认证相关请求头字典,格式:
|
|
116
|
+
{"Fmind-Auth": "Bearer <token>", "X-App-Code": "xxx", ...}
|
|
117
|
+
|
|
118
|
+
Example:
|
|
119
|
+
# In FastAPI handler:
|
|
120
|
+
def handler(request: Request):
|
|
121
|
+
set_request_auth({"Fmind-Auth": request.headers.get("Fmind-Auth")})
|
|
122
|
+
result = service_get_skill_by_code("my-skill")
|
|
123
|
+
"""
|
|
124
|
+
REQUEST_HEADERS.set(headers)
|
|
125
|
+
|
|
126
|
+
|
|
127
|
+
def get_request_auth() -> dict[str, str] | None:
|
|
128
|
+
"""获取当前请求的认证头。
|
|
129
|
+
|
|
130
|
+
通常在请求结束时自动调用(如果使用 request_context 管理器则无需手动调用)。
|
|
131
|
+
"""
|
|
132
|
+
return REQUEST_HEADERS.get()
|
|
133
|
+
|
|
134
|
+
|
|
135
|
+
def clear_request_auth() -> None:
|
|
136
|
+
"""清除本次请求的认证头。
|
|
137
|
+
|
|
138
|
+
通常在请求结束时自动调用(如果使用 request_context 管理器则无需手动调用)。
|
|
139
|
+
"""
|
|
140
|
+
REQUEST_HEADERS.set(None)
|
|
141
|
+
|
|
142
|
+
|
|
143
|
+
@contextmanager
|
|
144
|
+
def request_context(headers: dict[str, str]):
|
|
145
|
+
"""请求级认证上下文管理器。
|
|
146
|
+
|
|
147
|
+
自动在退出时清理认证上下文。推荐用于包装请求处理器。
|
|
148
|
+
|
|
149
|
+
Example:
|
|
150
|
+
def handler(request: Request):
|
|
151
|
+
with request_context({"Fmind-Auth": request.headers.get("Fmind-Auth")}):
|
|
152
|
+
result = service_get_skill_by_code("my-skill")
|
|
153
|
+
"""
|
|
154
|
+
token = REQUEST_HEADERS.set(headers)
|
|
155
|
+
try:
|
|
156
|
+
yield
|
|
157
|
+
finally:
|
|
158
|
+
REQUEST_HEADERS.reset(token)
|
|
159
|
+
|
|
160
|
+
|
|
84
161
|
def get_user_info_file_path() -> str:
|
|
85
162
|
"""返回用户信息文件路径。"""
|
|
86
163
|
return get_work_dir(USER_INFO_FILE)
|
|
@@ -127,7 +204,13 @@ def get_user_info(strict: bool = True) -> UserInfo | None:
|
|
|
127
204
|
|
|
128
205
|
|
|
129
206
|
def get_headers(strict: bool = True) -> Mapping[str, str]:
|
|
130
|
-
#
|
|
207
|
+
# 最高优先级:请求上下文中的认证头(web app 场景)
|
|
208
|
+
global REQUEST_HEADERS
|
|
209
|
+
request_headers = REQUEST_HEADERS.get()
|
|
210
|
+
if request_headers is not None:
|
|
211
|
+
return request_headers
|
|
212
|
+
|
|
213
|
+
# 降级:原有的 CLI/环境变量/file 认证逻辑
|
|
131
214
|
fmind_auth_headers = os.getenv("FMIND_AUTH_HEADERS", None)
|
|
132
215
|
if fmind_auth_headers is not None:
|
|
133
216
|
headers = from_json(fmind_auth_headers)
|
|
@@ -203,12 +286,32 @@ def refresh_token(response: httpx2.Response):
|
|
|
203
286
|
|
|
204
287
|
|
|
205
288
|
@contextmanager
|
|
206
|
-
def get_session(
|
|
289
|
+
def get_session(
|
|
290
|
+
strict: bool = True,
|
|
291
|
+
timeout: int = 10,
|
|
292
|
+
auth_headers: dict[str, str] | None = None,
|
|
293
|
+
):
|
|
207
294
|
"""获取请求 Session。
|
|
208
295
|
|
|
209
296
|
使用 httpx2 管理 HTTP 连接,base_url 指向 DataOps 服务。
|
|
297
|
+
|
|
298
|
+
Args:
|
|
299
|
+
strict: 是否要求认证
|
|
300
|
+
timeout: 请求超时秒数,默认 10s
|
|
301
|
+
auth_headers: 可选的认证头,用于一次性认证场景。
|
|
302
|
+
如果设置,会覆盖 contextvar 和模块级认证。
|
|
303
|
+
|
|
304
|
+
Example:
|
|
305
|
+
# 使用请求上下文认证(推荐):
|
|
306
|
+
set_request_auth({"Fmind-Auth": "Bearer token"})
|
|
307
|
+
with get_session() as session:
|
|
308
|
+
session.get("/api")
|
|
309
|
+
|
|
310
|
+
# 一次性认证(不常用):
|
|
311
|
+
with get_session(auth_headers={"Fmind-Auth": "Bearer token"}) as session:
|
|
312
|
+
session.get("/api")
|
|
210
313
|
"""
|
|
211
|
-
headers = get_headers(strict)
|
|
314
|
+
headers = auth_headers if auth_headers is not None else get_headers(strict)
|
|
212
315
|
with httpx2.Client(
|
|
213
316
|
headers=headers,
|
|
214
317
|
base_url=_config.base_url,
|
|
@@ -60,7 +60,9 @@ class MarkdownToTipTapParser:
|
|
|
60
60
|
node, index = self._parse_table(tokens, index)
|
|
61
61
|
content.append(node)
|
|
62
62
|
elif token.type == "html_block":
|
|
63
|
-
content.append(
|
|
63
|
+
content.append(
|
|
64
|
+
parse_utils.parse_paragraph([parse_utils.create_text_node(token.content)])
|
|
65
|
+
)
|
|
64
66
|
index += 1
|
|
65
67
|
else:
|
|
66
68
|
raise ValueError(f"Unsupported Markdown block token: {token.type}")
|
|
@@ -133,7 +135,9 @@ class MarkdownToTipTapParser:
|
|
|
133
135
|
if opening.type == "bullet_list_open"
|
|
134
136
|
else constants.NodeTypes.ORDERED_LIST
|
|
135
137
|
)
|
|
136
|
-
return parse_utils.create_node(
|
|
138
|
+
return parse_utils.create_node(
|
|
139
|
+
node_type, attrs=attrs, content=[item for item, _ in items]
|
|
140
|
+
), index
|
|
137
141
|
|
|
138
142
|
def _convert_task_item(self, paragraph: dict) -> dict | None:
|
|
139
143
|
if paragraph.get("type") != constants.NodeTypes.PARAGRAPH:
|
|
@@ -11,24 +11,22 @@ import json
|
|
|
11
11
|
from pathlib import Path
|
|
12
12
|
from unittest.mock import MagicMock
|
|
13
13
|
|
|
14
|
+
import dataops_sdk.session as session_module
|
|
14
15
|
import httpx2
|
|
15
16
|
import pytest
|
|
16
|
-
from pydantic import ValidationError
|
|
17
|
-
|
|
18
17
|
from dataops_sdk.session import (
|
|
19
18
|
DataOpsConfig,
|
|
20
19
|
configure,
|
|
21
20
|
get_application,
|
|
21
|
+
get_application_file_path,
|
|
22
22
|
get_config,
|
|
23
23
|
get_headers,
|
|
24
24
|
get_session,
|
|
25
25
|
get_user_info,
|
|
26
26
|
get_user_info_file_path,
|
|
27
|
-
get_application_file_path,
|
|
28
27
|
refresh_token,
|
|
29
28
|
)
|
|
30
|
-
|
|
31
|
-
|
|
29
|
+
from pydantic import ValidationError
|
|
32
30
|
|
|
33
31
|
# === DataOpsConfig ===
|
|
34
32
|
|
|
@@ -463,4 +461,4 @@ def test_get_session_closes_on_exception(mocker) -> None:
|
|
|
463
461
|
with get_session(strict=False):
|
|
464
462
|
raise RuntimeError("user code failed")
|
|
465
463
|
|
|
466
|
-
fake_client.close.assert_called()
|
|
464
|
+
fake_client.close.assert_called()
|
|
@@ -12,17 +12,15 @@ from pathlib import Path
|
|
|
12
12
|
from typing import ClassVar
|
|
13
13
|
|
|
14
14
|
import pytest
|
|
15
|
-
from pydantic import BaseModel
|
|
16
|
-
|
|
17
15
|
from dataops_sdk.utils import (
|
|
18
|
-
deep_merge,
|
|
19
16
|
decrypt_body,
|
|
17
|
+
deep_merge,
|
|
20
18
|
encrypt_body,
|
|
21
19
|
encrypt_hex,
|
|
22
20
|
filter_nodes_by_pattern,
|
|
23
21
|
get_work_dir,
|
|
24
22
|
)
|
|
25
|
-
|
|
23
|
+
from pydantic import BaseModel
|
|
26
24
|
|
|
27
25
|
# === 辅助 fixture:构造 SearchableNode 兼容对象 ===
|
|
28
26
|
|
|
@@ -314,4 +312,4 @@ def test_deep_merge_deeply_nested() -> None:
|
|
|
314
312
|
src = {"a": {"b": {"c": {"d": 1}}}}
|
|
315
313
|
dst = {"a": {"b": {"c": {"e": 2}}}}
|
|
316
314
|
merged = deep_merge(src, dst)
|
|
317
|
-
assert merged == {"a": {"b": {"c": {"d": 1, "e": 2}}}}
|
|
315
|
+
assert merged == {"a": {"b": {"c": {"d": 1, "e": 2}}}}
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{dataops_sdk-0.3.0 → dataops_sdk-0.3.1}/src/dataops_sdk/runner/schemas/nacos/nacos_exception.py
RENAMED
|
File without changes
|
{dataops_sdk-0.3.0 → dataops_sdk-0.3.1}/src/dataops_sdk/runner/schemas/nacos/naming_param.py
RENAMED
|
File without changes
|
{dataops_sdk-0.3.0 → dataops_sdk-0.3.1}/src/dataops_sdk/runner/schemas/nacos/naming_request.py
RENAMED
|
File without changes
|
{dataops_sdk-0.3.0 → dataops_sdk-0.3.1}/src/dataops_sdk/runner/schemas/nacos/naming_response.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|