hebra 0.1.0__py3-none-macosx_11_0_arm64.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.
- hebra/__init__.py +51 -0
- hebra/bin/.gitkeep +1 -0
- hebra/bin/core +0 -0
- hebra/lib/__init__.py +0 -0
- hebra/lib/service_connection.py +137 -0
- hebra/lib/utils.py +66 -0
- hebra/proto/common/v1/common.proto +50 -0
- hebra/proto/common/v1/common_pb2.py +43 -0
- hebra/proto/common/v1/common_pb2.pyi +45 -0
- hebra/proto/core/collector/v1/collector_service.proto +23 -0
- hebra/proto/core/collector/v1/collector_service_pb2.py +42 -0
- hebra/proto/core/collector/v1/collector_service_pb2.pyi +21 -0
- hebra/proto/core/collector/v1/collector_service_pb2_grpc.py +101 -0
- hebra/proto/core/health/v1/health_service.proto +92 -0
- hebra/proto/core/lifecycle/__init__.py +1 -0
- hebra/proto/core/lifecycle/v1/__init__.py +1 -0
- hebra/proto/core/lifecycle/v1/lifecycle_service.proto +24 -0
- hebra/proto/core/lifecycle/v1/lifecycle_service_pb2.py +41 -0
- hebra/proto/core/lifecycle/v1/lifecycle_service_pb2.pyi +17 -0
- hebra/proto/core/lifecycle/v1/lifecycle_service_pb2_grpc.py +102 -0
- hebra/proto/record/v1/record.proto +180 -0
- hebra/proto/record/v1/record_pb2.py +67 -0
- hebra/proto/record/v1/record_pb2.pyi +206 -0
- hebra/run/__init__.py +4 -0
- hebra/run/main.py +211 -0
- hebra/run/state.py +10 -0
- hebra/sdk.py +78 -0
- hebra-0.1.0.dist-info/METADATA +8 -0
- hebra-0.1.0.dist-info/RECORD +30 -0
- hebra-0.1.0.dist-info/WHEEL +4 -0
hebra/__init__.py
ADDED
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
"""hebra: SwanLab风格的实验追踪SDK(demo版本)。
|
|
2
|
+
|
|
3
|
+
使用方式:
|
|
4
|
+
import hebra
|
|
5
|
+
|
|
6
|
+
# 1. 初始化(启动Go服务进程)
|
|
7
|
+
run = hebra.init(project="my-project", logdir="./logs")
|
|
8
|
+
|
|
9
|
+
# 2. 记录数据
|
|
10
|
+
hebra.log({"loss": 0.1, "acc": 0.9})
|
|
11
|
+
# 或通过run对象
|
|
12
|
+
run.log({"loss": 0.1})
|
|
13
|
+
|
|
14
|
+
# 3. 可选:手动结束(不调用会自动结束)
|
|
15
|
+
hebra.finish()
|
|
16
|
+
"""
|
|
17
|
+
|
|
18
|
+
from __future__ import annotations
|
|
19
|
+
|
|
20
|
+
import sys
|
|
21
|
+
from pathlib import Path
|
|
22
|
+
|
|
23
|
+
# ============================================================================
|
|
24
|
+
# Proto 路径配置(必须在导入模块前完成)
|
|
25
|
+
# ============================================================================
|
|
26
|
+
|
|
27
|
+
PKG_ROOT = Path(__file__).resolve().parent
|
|
28
|
+
PKG_PROTO_ROOT = PKG_ROOT / "proto"
|
|
29
|
+
|
|
30
|
+
if str(PKG_PROTO_ROOT) not in sys.path and PKG_PROTO_ROOT.exists():
|
|
31
|
+
sys.path.append(str(PKG_PROTO_ROOT))
|
|
32
|
+
|
|
33
|
+
# ============================================================================
|
|
34
|
+
# 导入核心 API
|
|
35
|
+
# ============================================================================
|
|
36
|
+
|
|
37
|
+
from .run import HebraRun, HebraRunState, get_run
|
|
38
|
+
from .sdk import init, log, finish
|
|
39
|
+
|
|
40
|
+
# ============================================================================
|
|
41
|
+
# 导出
|
|
42
|
+
# ============================================================================
|
|
43
|
+
|
|
44
|
+
__all__ = [
|
|
45
|
+
"init",
|
|
46
|
+
"log",
|
|
47
|
+
"finish",
|
|
48
|
+
"get_run",
|
|
49
|
+
"HebraRun",
|
|
50
|
+
"HebraRunState",
|
|
51
|
+
]
|
hebra/bin/.gitkeep
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
|
hebra/bin/core
ADDED
|
Binary file
|
hebra/lib/__init__.py
ADDED
|
File without changes
|
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
import os
|
|
4
|
+
import shutil
|
|
5
|
+
import subprocess
|
|
6
|
+
import tempfile
|
|
7
|
+
import time
|
|
8
|
+
from pathlib import Path
|
|
9
|
+
from typing import Optional
|
|
10
|
+
|
|
11
|
+
import grpc
|
|
12
|
+
|
|
13
|
+
# Proto imports
|
|
14
|
+
from common.v1 import common_pb2
|
|
15
|
+
from core.collector.v1 import (
|
|
16
|
+
collector_service_pb2,
|
|
17
|
+
collector_service_pb2_grpc,
|
|
18
|
+
)
|
|
19
|
+
from core.lifecycle.v1 import (
|
|
20
|
+
lifecycle_service_pb2,
|
|
21
|
+
lifecycle_service_pb2_grpc,
|
|
22
|
+
)
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
class ServiceConnection:
|
|
26
|
+
"""管理与Go服务的连接(内部使用)"""
|
|
27
|
+
|
|
28
|
+
def __init__(self, db_path: str):
|
|
29
|
+
self._proc: Optional[subprocess.Popen] = None
|
|
30
|
+
self._channel: Optional[grpc.Channel] = None
|
|
31
|
+
self._workdir: Optional[Path] = None
|
|
32
|
+
self._db_path = db_path
|
|
33
|
+
|
|
34
|
+
def start(self) -> None:
|
|
35
|
+
"""启动Go服务进程"""
|
|
36
|
+
if self._proc is not None:
|
|
37
|
+
return
|
|
38
|
+
|
|
39
|
+
server_bin = find_server_bin()
|
|
40
|
+
self._workdir = Path(tempfile.mkdtemp(prefix="hebra-"))
|
|
41
|
+
port_file = self._workdir / "port.txt"
|
|
42
|
+
|
|
43
|
+
self._proc = subprocess.Popen(
|
|
44
|
+
[
|
|
45
|
+
str(server_bin),
|
|
46
|
+
"--pid",
|
|
47
|
+
str(os.getpid()),
|
|
48
|
+
"--port-file",
|
|
49
|
+
str(port_file),
|
|
50
|
+
"--db-path",
|
|
51
|
+
self._db_path,
|
|
52
|
+
],
|
|
53
|
+
cwd=self._workdir,
|
|
54
|
+
)
|
|
55
|
+
|
|
56
|
+
addr_line = wait_for_address(port_file)
|
|
57
|
+
kind, target = parse_address(addr_line)
|
|
58
|
+
self._channel = make_channel(kind, target)
|
|
59
|
+
|
|
60
|
+
def upload(
|
|
61
|
+
self, data: common_pb2.KeyValueList
|
|
62
|
+
) -> collector_service_pb2.CollectorUploadResponse:
|
|
63
|
+
"""上传数据到Go服务"""
|
|
64
|
+
if self._channel is None:
|
|
65
|
+
raise RuntimeError("服务未启动")
|
|
66
|
+
stub = collector_service_pb2_grpc.CollectorStub(self._channel)
|
|
67
|
+
req = collector_service_pb2.CollectorUploadRequest(data=data)
|
|
68
|
+
return stub.Upload(req, timeout=5)
|
|
69
|
+
|
|
70
|
+
def shutdown(self, exit_code: int = 0, timeout: float = 5.0) -> None:
|
|
71
|
+
"""关闭Go服务"""
|
|
72
|
+
if self._channel is not None and self._proc is not None:
|
|
73
|
+
try:
|
|
74
|
+
stub = lifecycle_service_pb2_grpc.LifecycleStub(self._channel)
|
|
75
|
+
req = lifecycle_service_pb2.ShutdownRequest(exit_code=exit_code)
|
|
76
|
+
stub.Shutdown(req, timeout=2)
|
|
77
|
+
except grpc.RpcError:
|
|
78
|
+
pass
|
|
79
|
+
finally:
|
|
80
|
+
self._channel.close()
|
|
81
|
+
self._channel = None
|
|
82
|
+
|
|
83
|
+
if self._proc is not None:
|
|
84
|
+
try:
|
|
85
|
+
self._proc.wait(timeout=timeout)
|
|
86
|
+
except subprocess.TimeoutExpired:
|
|
87
|
+
self._proc.kill()
|
|
88
|
+
self._proc.wait()
|
|
89
|
+
self._proc = None
|
|
90
|
+
|
|
91
|
+
if self._workdir is not None:
|
|
92
|
+
shutil.rmtree(self._workdir, ignore_errors=True)
|
|
93
|
+
self._workdir = None
|
|
94
|
+
|
|
95
|
+
|
|
96
|
+
# 内部辅助函数
|
|
97
|
+
|
|
98
|
+
|
|
99
|
+
def find_server_bin() -> Path:
|
|
100
|
+
"""查找Go服务二进制文件"""
|
|
101
|
+
from .. import PKG_ROOT
|
|
102
|
+
|
|
103
|
+
exe_name = "core.exe" if os.name == "nt" else "core"
|
|
104
|
+
bin_path = PKG_ROOT / "bin" / exe_name
|
|
105
|
+
if bin_path.exists() and bin_path.is_file():
|
|
106
|
+
return bin_path
|
|
107
|
+
raise FileNotFoundError(f"服务二进制文件未找到: {bin_path}")
|
|
108
|
+
|
|
109
|
+
|
|
110
|
+
def wait_for_address(path: Path, timeout: float = 10.0) -> str:
|
|
111
|
+
"""等待端口文件生成并读取地址"""
|
|
112
|
+
deadline = time.time() + timeout
|
|
113
|
+
while time.time() < deadline:
|
|
114
|
+
if path.exists():
|
|
115
|
+
text = path.read_text().strip()
|
|
116
|
+
if text:
|
|
117
|
+
return text.splitlines()[0].strip()
|
|
118
|
+
time.sleep(0.1)
|
|
119
|
+
raise TimeoutError(f"端口文件未在{timeout}秒内生成")
|
|
120
|
+
|
|
121
|
+
|
|
122
|
+
def parse_address(line: str) -> tuple:
|
|
123
|
+
"""解析地址格式"""
|
|
124
|
+
if line.startswith("unix://"):
|
|
125
|
+
return "unix", line[len("unix://") :]
|
|
126
|
+
if line.startswith("tcp://"):
|
|
127
|
+
return "tcp", line[len("tcp://") :]
|
|
128
|
+
raise ValueError(f"未知地址格式: {line}")
|
|
129
|
+
|
|
130
|
+
|
|
131
|
+
def make_channel(kind: str, target: str) -> grpc.Channel:
|
|
132
|
+
"""创建gRPC通道"""
|
|
133
|
+
if kind == "unix":
|
|
134
|
+
return grpc.insecure_channel(f"unix://{target}")
|
|
135
|
+
if target.startswith(":"):
|
|
136
|
+
target = f"localhost{target}"
|
|
137
|
+
return grpc.insecure_channel(target)
|
hebra/lib/utils.py
ADDED
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from typing import Any, Mapping, TYPE_CHECKING
|
|
4
|
+
|
|
5
|
+
if TYPE_CHECKING:
|
|
6
|
+
from ..run import HebraRun
|
|
7
|
+
|
|
8
|
+
# Proto imports (需要在包初始化时设置好 sys.path)
|
|
9
|
+
from common.v1 import common_pb2
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
def should_call_before_init(error_message: str):
|
|
13
|
+
"""装饰器:限制必须在init之前调用"""
|
|
14
|
+
from ..run import HebraRun
|
|
15
|
+
|
|
16
|
+
def decorator(func):
|
|
17
|
+
def wrapper(*args, **kwargs):
|
|
18
|
+
if HebraRun.is_started():
|
|
19
|
+
raise RuntimeError(error_message)
|
|
20
|
+
return func(*args, **kwargs)
|
|
21
|
+
|
|
22
|
+
return wrapper
|
|
23
|
+
|
|
24
|
+
return decorator
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
def should_call_after_init(error_message: str):
|
|
28
|
+
"""装饰器:限制必须在init之后调用"""
|
|
29
|
+
from ..run import HebraRun
|
|
30
|
+
|
|
31
|
+
def decorator(func):
|
|
32
|
+
def wrapper(*args, **kwargs):
|
|
33
|
+
if not HebraRun.is_started():
|
|
34
|
+
raise RuntimeError(error_message)
|
|
35
|
+
return func(*args, **kwargs)
|
|
36
|
+
|
|
37
|
+
return wrapper
|
|
38
|
+
|
|
39
|
+
return decorator
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
def to_any(value: Any) -> common_pb2.AnyValue:
|
|
43
|
+
"""将Python值转换为AnyValue"""
|
|
44
|
+
if isinstance(value, bool):
|
|
45
|
+
return common_pb2.AnyValue(bool_value=value)
|
|
46
|
+
if isinstance(value, int):
|
|
47
|
+
return common_pb2.AnyValue(int_value=value)
|
|
48
|
+
if isinstance(value, float):
|
|
49
|
+
return common_pb2.AnyValue(double_value=value)
|
|
50
|
+
if isinstance(value, str):
|
|
51
|
+
return common_pb2.AnyValue(string_value=value)
|
|
52
|
+
if isinstance(value, (list, tuple)):
|
|
53
|
+
arr = common_pb2.ArrayValue(values=[to_any(v) for v in value])
|
|
54
|
+
return common_pb2.AnyValue(array_value=arr)
|
|
55
|
+
# 其他类型转为字符串
|
|
56
|
+
return common_pb2.AnyValue(string_value=str(value))
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
def kvs_from_mapping(kvs: Mapping[str, Any]) -> common_pb2.KeyValueList:
|
|
60
|
+
"""将字典转换为KeyValueList"""
|
|
61
|
+
kv_list = common_pb2.KeyValueList()
|
|
62
|
+
for k, v in kvs.items():
|
|
63
|
+
if not k:
|
|
64
|
+
continue
|
|
65
|
+
kv_list.values.append(common_pb2.KeyValue(key=str(k), value=to_any(v)))
|
|
66
|
+
return kv_list
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
syntax = "proto3";
|
|
2
|
+
|
|
3
|
+
package swanlab.proto.common.v1;
|
|
4
|
+
|
|
5
|
+
option go_package = "core/pkg/pb";
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
// AnyValue is used to represent any type of attribute value. AnyValue may contain a
|
|
9
|
+
// primitive value such as a string or integer or it may contain an arbitrary nested
|
|
10
|
+
// object containing arrays, key-value lists and primitives.
|
|
11
|
+
message AnyValue {
|
|
12
|
+
// The value is one of the listed fields. It is valid for all values to be unspecified
|
|
13
|
+
// in which case this AnyValue is considered to be "empty".
|
|
14
|
+
oneof value {
|
|
15
|
+
string string_value = 1;
|
|
16
|
+
bool bool_value = 2;
|
|
17
|
+
int64 int_value = 3;
|
|
18
|
+
double double_value = 4;
|
|
19
|
+
ArrayValue array_value = 5;
|
|
20
|
+
KeyValueList kvlist_value = 6;
|
|
21
|
+
bytes bytes_value = 7;
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
// ArrayValue is a list of AnyValue messages. We need ArrayValue as a message
|
|
26
|
+
// since oneof in AnyValue does not allow repeated fields.
|
|
27
|
+
message ArrayValue {
|
|
28
|
+
// Array of values. The array may be empty (contain 0 elements).
|
|
29
|
+
repeated AnyValue values = 1;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
// KeyValueList is a list of KeyValue messages. We need KeyValueList as a message
|
|
33
|
+
// since `oneof` in AnyValue does not allow repeated fields. Everywhere else where we need
|
|
34
|
+
// a list of KeyValue messages (e.g. in Span) we use `repeated KeyValue` directly to
|
|
35
|
+
// avoid unnecessary extra wrapping (which slows down the protocol). The 2 approaches
|
|
36
|
+
// are semantically equivalent.
|
|
37
|
+
message KeyValueList {
|
|
38
|
+
// A collection of key/value pairs of key-value pairs. The list may be empty (may
|
|
39
|
+
// contain 0 elements).
|
|
40
|
+
// The keys MUST be unique (it is not allowed to have more than one
|
|
41
|
+
// value with the same key).
|
|
42
|
+
repeated KeyValue values = 1;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
// KeyValue is a key-value pair that is used to store Span attributes, Link
|
|
46
|
+
// attributes, etc.
|
|
47
|
+
message KeyValue {
|
|
48
|
+
string key = 1;
|
|
49
|
+
AnyValue value = 2;
|
|
50
|
+
}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
# Generated by the protocol buffer compiler. DO NOT EDIT!
|
|
3
|
+
# NO CHECKED-IN PROTOBUF GENCODE
|
|
4
|
+
# source: common/v1/common.proto
|
|
5
|
+
# Protobuf Python Version: 6.31.1
|
|
6
|
+
"""Generated protocol buffer code."""
|
|
7
|
+
from google.protobuf import descriptor as _descriptor
|
|
8
|
+
from google.protobuf import descriptor_pool as _descriptor_pool
|
|
9
|
+
from google.protobuf import runtime_version as _runtime_version
|
|
10
|
+
from google.protobuf import symbol_database as _symbol_database
|
|
11
|
+
from google.protobuf.internal import builder as _builder
|
|
12
|
+
_runtime_version.ValidateProtobufRuntimeVersion(
|
|
13
|
+
_runtime_version.Domain.PUBLIC,
|
|
14
|
+
6,
|
|
15
|
+
31,
|
|
16
|
+
1,
|
|
17
|
+
'',
|
|
18
|
+
'common/v1/common.proto'
|
|
19
|
+
)
|
|
20
|
+
# @@protoc_insertion_point(imports)
|
|
21
|
+
|
|
22
|
+
_sym_db = _symbol_database.Default()
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x16\x63ommon/v1/common.proto\x12\x17swanlab.proto.common.v1\"\x80\x02\n\x08\x41nyValue\x12\x16\n\x0cstring_value\x18\x01 \x01(\tH\x00\x12\x14\n\nbool_value\x18\x02 \x01(\x08H\x00\x12\x13\n\tint_value\x18\x03 \x01(\x03H\x00\x12\x16\n\x0c\x64ouble_value\x18\x04 \x01(\x01H\x00\x12:\n\x0b\x61rray_value\x18\x05 \x01(\x0b\x32#.swanlab.proto.common.v1.ArrayValueH\x00\x12=\n\x0ckvlist_value\x18\x06 \x01(\x0b\x32%.swanlab.proto.common.v1.KeyValueListH\x00\x12\x15\n\x0b\x62ytes_value\x18\x07 \x01(\x0cH\x00\x42\x07\n\x05value\"?\n\nArrayValue\x12\x31\n\x06values\x18\x01 \x03(\x0b\x32!.swanlab.proto.common.v1.AnyValue\"A\n\x0cKeyValueList\x12\x31\n\x06values\x18\x01 \x03(\x0b\x32!.swanlab.proto.common.v1.KeyValue\"I\n\x08KeyValue\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\x30\n\x05value\x18\x02 \x01(\x0b\x32!.swanlab.proto.common.v1.AnyValueB\rZ\x0b\x63ore/pkg/pbb\x06proto3')
|
|
28
|
+
|
|
29
|
+
_globals = globals()
|
|
30
|
+
_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals)
|
|
31
|
+
_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'common.v1.common_pb2', _globals)
|
|
32
|
+
if not _descriptor._USE_C_DESCRIPTORS:
|
|
33
|
+
_globals['DESCRIPTOR']._loaded_options = None
|
|
34
|
+
_globals['DESCRIPTOR']._serialized_options = b'Z\013core/pkg/pb'
|
|
35
|
+
_globals['_ANYVALUE']._serialized_start=52
|
|
36
|
+
_globals['_ANYVALUE']._serialized_end=308
|
|
37
|
+
_globals['_ARRAYVALUE']._serialized_start=310
|
|
38
|
+
_globals['_ARRAYVALUE']._serialized_end=373
|
|
39
|
+
_globals['_KEYVALUELIST']._serialized_start=375
|
|
40
|
+
_globals['_KEYVALUELIST']._serialized_end=440
|
|
41
|
+
_globals['_KEYVALUE']._serialized_start=442
|
|
42
|
+
_globals['_KEYVALUE']._serialized_end=515
|
|
43
|
+
# @@protoc_insertion_point(module_scope)
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
from google.protobuf.internal import containers as _containers
|
|
2
|
+
from google.protobuf import descriptor as _descriptor
|
|
3
|
+
from google.protobuf import message as _message
|
|
4
|
+
from collections.abc import Iterable as _Iterable, Mapping as _Mapping
|
|
5
|
+
from typing import ClassVar as _ClassVar, Optional as _Optional, Union as _Union
|
|
6
|
+
|
|
7
|
+
DESCRIPTOR: _descriptor.FileDescriptor
|
|
8
|
+
|
|
9
|
+
class AnyValue(_message.Message):
|
|
10
|
+
__slots__ = ("string_value", "bool_value", "int_value", "double_value", "array_value", "kvlist_value", "bytes_value")
|
|
11
|
+
STRING_VALUE_FIELD_NUMBER: _ClassVar[int]
|
|
12
|
+
BOOL_VALUE_FIELD_NUMBER: _ClassVar[int]
|
|
13
|
+
INT_VALUE_FIELD_NUMBER: _ClassVar[int]
|
|
14
|
+
DOUBLE_VALUE_FIELD_NUMBER: _ClassVar[int]
|
|
15
|
+
ARRAY_VALUE_FIELD_NUMBER: _ClassVar[int]
|
|
16
|
+
KVLIST_VALUE_FIELD_NUMBER: _ClassVar[int]
|
|
17
|
+
BYTES_VALUE_FIELD_NUMBER: _ClassVar[int]
|
|
18
|
+
string_value: str
|
|
19
|
+
bool_value: bool
|
|
20
|
+
int_value: int
|
|
21
|
+
double_value: float
|
|
22
|
+
array_value: ArrayValue
|
|
23
|
+
kvlist_value: KeyValueList
|
|
24
|
+
bytes_value: bytes
|
|
25
|
+
def __init__(self, string_value: _Optional[str] = ..., bool_value: bool = ..., int_value: _Optional[int] = ..., double_value: _Optional[float] = ..., array_value: _Optional[_Union[ArrayValue, _Mapping]] = ..., kvlist_value: _Optional[_Union[KeyValueList, _Mapping]] = ..., bytes_value: _Optional[bytes] = ...) -> None: ...
|
|
26
|
+
|
|
27
|
+
class ArrayValue(_message.Message):
|
|
28
|
+
__slots__ = ("values",)
|
|
29
|
+
VALUES_FIELD_NUMBER: _ClassVar[int]
|
|
30
|
+
values: _containers.RepeatedCompositeFieldContainer[AnyValue]
|
|
31
|
+
def __init__(self, values: _Optional[_Iterable[_Union[AnyValue, _Mapping]]] = ...) -> None: ...
|
|
32
|
+
|
|
33
|
+
class KeyValueList(_message.Message):
|
|
34
|
+
__slots__ = ("values",)
|
|
35
|
+
VALUES_FIELD_NUMBER: _ClassVar[int]
|
|
36
|
+
values: _containers.RepeatedCompositeFieldContainer[KeyValue]
|
|
37
|
+
def __init__(self, values: _Optional[_Iterable[_Union[KeyValue, _Mapping]]] = ...) -> None: ...
|
|
38
|
+
|
|
39
|
+
class KeyValue(_message.Message):
|
|
40
|
+
__slots__ = ("key", "value")
|
|
41
|
+
KEY_FIELD_NUMBER: _ClassVar[int]
|
|
42
|
+
VALUE_FIELD_NUMBER: _ClassVar[int]
|
|
43
|
+
key: str
|
|
44
|
+
value: AnyValue
|
|
45
|
+
def __init__(self, key: _Optional[str] = ..., value: _Optional[_Union[AnyValue, _Mapping]] = ...) -> None: ...
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
syntax = "proto3";
|
|
2
|
+
|
|
3
|
+
package swanlab.proto.core.collector.v1;
|
|
4
|
+
|
|
5
|
+
import "common/v1/common.proto";
|
|
6
|
+
|
|
7
|
+
option go_package = "core/pkg/pb";
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
message CollectorUploadRequest {
|
|
11
|
+
swanlab.proto.common.v1.KeyValueList data = 1;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
message CollectorUploadResponse {
|
|
15
|
+
bool success = 1;
|
|
16
|
+
string message = 2;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
// Collector is an RPC service responsible for aggregating and reporting data
|
|
20
|
+
service Collector {
|
|
21
|
+
// Upload allows clients to send data to the collector.
|
|
22
|
+
rpc Upload(CollectorUploadRequest) returns (CollectorUploadResponse);
|
|
23
|
+
}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
# Generated by the protocol buffer compiler. DO NOT EDIT!
|
|
3
|
+
# NO CHECKED-IN PROTOBUF GENCODE
|
|
4
|
+
# source: core/collector/v1/collector_service.proto
|
|
5
|
+
# Protobuf Python Version: 6.31.1
|
|
6
|
+
"""Generated protocol buffer code."""
|
|
7
|
+
from google.protobuf import descriptor as _descriptor
|
|
8
|
+
from google.protobuf import descriptor_pool as _descriptor_pool
|
|
9
|
+
from google.protobuf import runtime_version as _runtime_version
|
|
10
|
+
from google.protobuf import symbol_database as _symbol_database
|
|
11
|
+
from google.protobuf.internal import builder as _builder
|
|
12
|
+
_runtime_version.ValidateProtobufRuntimeVersion(
|
|
13
|
+
_runtime_version.Domain.PUBLIC,
|
|
14
|
+
6,
|
|
15
|
+
31,
|
|
16
|
+
1,
|
|
17
|
+
'',
|
|
18
|
+
'core/collector/v1/collector_service.proto'
|
|
19
|
+
)
|
|
20
|
+
# @@protoc_insertion_point(imports)
|
|
21
|
+
|
|
22
|
+
_sym_db = _symbol_database.Default()
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
from common.v1 import common_pb2 as common_dot_v1_dot_common__pb2
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n)core/collector/v1/collector_service.proto\x12\x1fswanlab.proto.core.collector.v1\x1a\x16\x63ommon/v1/common.proto\"M\n\x16\x43ollectorUploadRequest\x12\x33\n\x04\x64\x61ta\x18\x01 \x01(\x0b\x32%.swanlab.proto.common.v1.KeyValueList\";\n\x17\x43ollectorUploadResponse\x12\x0f\n\x07success\x18\x01 \x01(\x08\x12\x0f\n\x07message\x18\x02 \x01(\t2\x88\x01\n\tCollector\x12{\n\x06Upload\x12\x37.swanlab.proto.core.collector.v1.CollectorUploadRequest\x1a\x38.swanlab.proto.core.collector.v1.CollectorUploadResponseB\rZ\x0b\x63ore/pkg/pbb\x06proto3')
|
|
29
|
+
|
|
30
|
+
_globals = globals()
|
|
31
|
+
_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals)
|
|
32
|
+
_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'core.collector.v1.collector_service_pb2', _globals)
|
|
33
|
+
if not _descriptor._USE_C_DESCRIPTORS:
|
|
34
|
+
_globals['DESCRIPTOR']._loaded_options = None
|
|
35
|
+
_globals['DESCRIPTOR']._serialized_options = b'Z\013core/pkg/pb'
|
|
36
|
+
_globals['_COLLECTORUPLOADREQUEST']._serialized_start=102
|
|
37
|
+
_globals['_COLLECTORUPLOADREQUEST']._serialized_end=179
|
|
38
|
+
_globals['_COLLECTORUPLOADRESPONSE']._serialized_start=181
|
|
39
|
+
_globals['_COLLECTORUPLOADRESPONSE']._serialized_end=240
|
|
40
|
+
_globals['_COLLECTOR']._serialized_start=243
|
|
41
|
+
_globals['_COLLECTOR']._serialized_end=379
|
|
42
|
+
# @@protoc_insertion_point(module_scope)
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
from common.v1 import common_pb2 as _common_pb2
|
|
2
|
+
from google.protobuf import descriptor as _descriptor
|
|
3
|
+
from google.protobuf import message as _message
|
|
4
|
+
from collections.abc import Mapping as _Mapping
|
|
5
|
+
from typing import ClassVar as _ClassVar, Optional as _Optional, Union as _Union
|
|
6
|
+
|
|
7
|
+
DESCRIPTOR: _descriptor.FileDescriptor
|
|
8
|
+
|
|
9
|
+
class CollectorUploadRequest(_message.Message):
|
|
10
|
+
__slots__ = ("data",)
|
|
11
|
+
DATA_FIELD_NUMBER: _ClassVar[int]
|
|
12
|
+
data: _common_pb2.KeyValueList
|
|
13
|
+
def __init__(self, data: _Optional[_Union[_common_pb2.KeyValueList, _Mapping]] = ...) -> None: ...
|
|
14
|
+
|
|
15
|
+
class CollectorUploadResponse(_message.Message):
|
|
16
|
+
__slots__ = ("success", "message")
|
|
17
|
+
SUCCESS_FIELD_NUMBER: _ClassVar[int]
|
|
18
|
+
MESSAGE_FIELD_NUMBER: _ClassVar[int]
|
|
19
|
+
success: bool
|
|
20
|
+
message: str
|
|
21
|
+
def __init__(self, success: bool = ..., message: _Optional[str] = ...) -> None: ...
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
# Generated by the gRPC Python protocol compiler plugin. DO NOT EDIT!
|
|
2
|
+
"""Client and server classes corresponding to protobuf-defined services."""
|
|
3
|
+
import grpc
|
|
4
|
+
import warnings
|
|
5
|
+
|
|
6
|
+
from core.collector.v1 import collector_service_pb2 as core_dot_collector_dot_v1_dot_collector__service__pb2
|
|
7
|
+
|
|
8
|
+
GRPC_GENERATED_VERSION = '1.76.0'
|
|
9
|
+
GRPC_VERSION = grpc.__version__
|
|
10
|
+
_version_not_supported = False
|
|
11
|
+
|
|
12
|
+
try:
|
|
13
|
+
from grpc._utilities import first_version_is_lower
|
|
14
|
+
_version_not_supported = first_version_is_lower(GRPC_VERSION, GRPC_GENERATED_VERSION)
|
|
15
|
+
except ImportError:
|
|
16
|
+
_version_not_supported = True
|
|
17
|
+
|
|
18
|
+
if _version_not_supported:
|
|
19
|
+
raise RuntimeError(
|
|
20
|
+
f'The grpc package installed is at version {GRPC_VERSION},'
|
|
21
|
+
+ ' but the generated code in core/collector/v1/collector_service_pb2_grpc.py depends on'
|
|
22
|
+
+ f' grpcio>={GRPC_GENERATED_VERSION}.'
|
|
23
|
+
+ f' Please upgrade your grpc module to grpcio>={GRPC_GENERATED_VERSION}'
|
|
24
|
+
+ f' or downgrade your generated code using grpcio-tools<={GRPC_VERSION}.'
|
|
25
|
+
)
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
class CollectorStub(object):
|
|
29
|
+
"""Collector is an RPC service responsible for aggregating and reporting data
|
|
30
|
+
"""
|
|
31
|
+
|
|
32
|
+
def __init__(self, channel):
|
|
33
|
+
"""Constructor.
|
|
34
|
+
|
|
35
|
+
Args:
|
|
36
|
+
channel: A grpc.Channel.
|
|
37
|
+
"""
|
|
38
|
+
self.Upload = channel.unary_unary(
|
|
39
|
+
'/swanlab.proto.core.collector.v1.Collector/Upload',
|
|
40
|
+
request_serializer=core_dot_collector_dot_v1_dot_collector__service__pb2.CollectorUploadRequest.SerializeToString,
|
|
41
|
+
response_deserializer=core_dot_collector_dot_v1_dot_collector__service__pb2.CollectorUploadResponse.FromString,
|
|
42
|
+
_registered_method=True)
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
class CollectorServicer(object):
|
|
46
|
+
"""Collector is an RPC service responsible for aggregating and reporting data
|
|
47
|
+
"""
|
|
48
|
+
|
|
49
|
+
def Upload(self, request, context):
|
|
50
|
+
"""Upload allows clients to send data to the collector.
|
|
51
|
+
"""
|
|
52
|
+
context.set_code(grpc.StatusCode.UNIMPLEMENTED)
|
|
53
|
+
context.set_details('Method not implemented!')
|
|
54
|
+
raise NotImplementedError('Method not implemented!')
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
def add_CollectorServicer_to_server(servicer, server):
|
|
58
|
+
rpc_method_handlers = {
|
|
59
|
+
'Upload': grpc.unary_unary_rpc_method_handler(
|
|
60
|
+
servicer.Upload,
|
|
61
|
+
request_deserializer=core_dot_collector_dot_v1_dot_collector__service__pb2.CollectorUploadRequest.FromString,
|
|
62
|
+
response_serializer=core_dot_collector_dot_v1_dot_collector__service__pb2.CollectorUploadResponse.SerializeToString,
|
|
63
|
+
),
|
|
64
|
+
}
|
|
65
|
+
generic_handler = grpc.method_handlers_generic_handler(
|
|
66
|
+
'swanlab.proto.core.collector.v1.Collector', rpc_method_handlers)
|
|
67
|
+
server.add_generic_rpc_handlers((generic_handler,))
|
|
68
|
+
server.add_registered_method_handlers('swanlab.proto.core.collector.v1.Collector', rpc_method_handlers)
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+
# This class is part of an EXPERIMENTAL API.
|
|
72
|
+
class Collector(object):
|
|
73
|
+
"""Collector is an RPC service responsible for aggregating and reporting data
|
|
74
|
+
"""
|
|
75
|
+
|
|
76
|
+
@staticmethod
|
|
77
|
+
def Upload(request,
|
|
78
|
+
target,
|
|
79
|
+
options=(),
|
|
80
|
+
channel_credentials=None,
|
|
81
|
+
call_credentials=None,
|
|
82
|
+
insecure=False,
|
|
83
|
+
compression=None,
|
|
84
|
+
wait_for_ready=None,
|
|
85
|
+
timeout=None,
|
|
86
|
+
metadata=None):
|
|
87
|
+
return grpc.experimental.unary_unary(
|
|
88
|
+
request,
|
|
89
|
+
target,
|
|
90
|
+
'/swanlab.proto.core.collector.v1.Collector/Upload',
|
|
91
|
+
core_dot_collector_dot_v1_dot_collector__service__pb2.CollectorUploadRequest.SerializeToString,
|
|
92
|
+
core_dot_collector_dot_v1_dot_collector__service__pb2.CollectorUploadResponse.FromString,
|
|
93
|
+
options,
|
|
94
|
+
channel_credentials,
|
|
95
|
+
insecure,
|
|
96
|
+
call_credentials,
|
|
97
|
+
compression,
|
|
98
|
+
wait_for_ready,
|
|
99
|
+
timeout,
|
|
100
|
+
metadata,
|
|
101
|
+
_registered_method=True)
|