divi 0.0.1b0__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.
- divi/__init__.py +18 -0
- divi/decorators/__init__.py +4 -0
- divi/decorators/collect.py +34 -0
- divi/decorators/obs_openai.py +48 -0
- divi/decorators/observable.py +91 -0
- divi/decorators/observe.py +47 -0
- divi/evaluation/__init__.py +4 -0
- divi/evaluation/evaluate.py +61 -0
- divi/evaluation/evaluator.py +174 -0
- divi/evaluation/prompts.py +19 -0
- divi/evaluation/scores.py +8 -0
- divi/proto/common/v1/common.proto +49 -0
- divi/proto/common/v1/common_pb2.py +43 -0
- divi/proto/common/v1/common_pb2.pyi +44 -0
- divi/proto/core/health/v1/health_service.proto +17 -0
- divi/proto/core/health/v1/health_service_pb2.py +41 -0
- divi/proto/core/health/v1/health_service_pb2.pyi +19 -0
- divi/proto/core/health/v1/health_service_pb2_grpc.py +100 -0
- divi/proto/metric/v1/metric.proto +26 -0
- divi/proto/metric/v1/metric_pb2.py +40 -0
- divi/proto/metric/v1/metric_pb2.pyi +25 -0
- divi/proto/trace/v1/trace.proto +50 -0
- divi/proto/trace/v1/trace_pb2.py +42 -0
- divi/proto/trace/v1/trace_pb2.pyi +42 -0
- divi/services/__init__.py +7 -0
- divi/services/auth/__init__.py +4 -0
- divi/services/auth/auth.py +13 -0
- divi/services/auth/init.py +22 -0
- divi/services/auth/tokman.py +42 -0
- divi/services/core/__init__.py +5 -0
- divi/services/core/core.py +35 -0
- divi/services/core/finish.py +15 -0
- divi/services/core/init.py +70 -0
- divi/services/datapark/__init__.py +4 -0
- divi/services/datapark/datapark.py +91 -0
- divi/services/datapark/init.py +21 -0
- divi/services/finish.py +9 -0
- divi/services/init.py +10 -0
- divi/services/service.py +54 -0
- divi/session/__init__.py +3 -0
- divi/session/session.py +40 -0
- divi/session/setup.py +48 -0
- divi/session/teardown.py +7 -0
- divi/signals/__init__.py +3 -0
- divi/signals/span.py +83 -0
- divi/signals/trace.py +79 -0
- divi/utils.py +49 -0
- divi-0.0.1b0.dist-info/METADATA +18 -0
- divi-0.0.1b0.dist-info/RECORD +51 -0
- divi-0.0.1b0.dist-info/WHEEL +4 -0
- divi-0.0.1b0.dist-info/licenses/LICENSE +21 -0
@@ -0,0 +1,41 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
# Generated by the protocol buffer compiler. DO NOT EDIT!
|
3
|
+
# NO CHECKED-IN PROTOBUF GENCODE
|
4
|
+
# source: divi/proto/core/health/v1/health_service.proto
|
5
|
+
# Protobuf Python Version: 5.29.0
|
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
|
+
5,
|
15
|
+
29,
|
16
|
+
0,
|
17
|
+
'',
|
18
|
+
'divi/proto/core/health/v1/health_service.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.divi/proto/core/health/v1/health_service.proto\x12\x19\x64ivi.proto.core.health.v1\"%\n\x12HealthCheckRequest\x12\x0f\n\x07version\x18\x01 \x01(\t\"6\n\x13HealthCheckResponse\x12\x0e\n\x06status\x18\x01 \x01(\x08\x12\x0f\n\x07message\x18\x02 \x01(\t2y\n\rHealthService\x12h\n\x05\x43heck\x12-.divi.proto.core.health.v1.HealthCheckRequest\x1a..divi.proto.core.health.v1.HealthCheckResponse\"\x00\x42\rZ\x0bservices/pbb\x06proto3')
|
28
|
+
|
29
|
+
_globals = globals()
|
30
|
+
_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals)
|
31
|
+
_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'divi.proto.core.health.v1.health_service_pb2', _globals)
|
32
|
+
if not _descriptor._USE_C_DESCRIPTORS:
|
33
|
+
_globals['DESCRIPTOR']._loaded_options = None
|
34
|
+
_globals['DESCRIPTOR']._serialized_options = b'Z\013services/pb'
|
35
|
+
_globals['_HEALTHCHECKREQUEST']._serialized_start=77
|
36
|
+
_globals['_HEALTHCHECKREQUEST']._serialized_end=114
|
37
|
+
_globals['_HEALTHCHECKRESPONSE']._serialized_start=116
|
38
|
+
_globals['_HEALTHCHECKRESPONSE']._serialized_end=170
|
39
|
+
_globals['_HEALTHSERVICE']._serialized_start=172
|
40
|
+
_globals['_HEALTHSERVICE']._serialized_end=293
|
41
|
+
# @@protoc_insertion_point(module_scope)
|
@@ -0,0 +1,19 @@
|
|
1
|
+
from google.protobuf import descriptor as _descriptor
|
2
|
+
from google.protobuf import message as _message
|
3
|
+
from typing import ClassVar as _ClassVar, Optional as _Optional
|
4
|
+
|
5
|
+
DESCRIPTOR: _descriptor.FileDescriptor
|
6
|
+
|
7
|
+
class HealthCheckRequest(_message.Message):
|
8
|
+
__slots__ = ("version",)
|
9
|
+
VERSION_FIELD_NUMBER: _ClassVar[int]
|
10
|
+
version: str
|
11
|
+
def __init__(self, version: _Optional[str] = ...) -> None: ...
|
12
|
+
|
13
|
+
class HealthCheckResponse(_message.Message):
|
14
|
+
__slots__ = ("status", "message")
|
15
|
+
STATUS_FIELD_NUMBER: _ClassVar[int]
|
16
|
+
MESSAGE_FIELD_NUMBER: _ClassVar[int]
|
17
|
+
status: bool
|
18
|
+
message: str
|
19
|
+
def __init__(self, status: bool = ..., message: _Optional[str] = ...) -> None: ...
|
@@ -0,0 +1,100 @@
|
|
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 divi.proto.core.health.v1 import health_service_pb2 as divi_dot_proto_dot_core_dot_health_dot_v1_dot_health__service__pb2
|
7
|
+
|
8
|
+
GRPC_GENERATED_VERSION = '1.71.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
|
+
+ f' but the generated code in divi/proto/core/health/v1/health_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 HealthServiceStub(object):
|
29
|
+
"""HealthService is a service that implements health check.
|
30
|
+
"""
|
31
|
+
|
32
|
+
def __init__(self, channel):
|
33
|
+
"""Constructor.
|
34
|
+
|
35
|
+
Args:
|
36
|
+
channel: A grpc.Channel.
|
37
|
+
"""
|
38
|
+
self.Check = channel.unary_unary(
|
39
|
+
'/divi.proto.core.health.v1.HealthService/Check',
|
40
|
+
request_serializer=divi_dot_proto_dot_core_dot_health_dot_v1_dot_health__service__pb2.HealthCheckRequest.SerializeToString,
|
41
|
+
response_deserializer=divi_dot_proto_dot_core_dot_health_dot_v1_dot_health__service__pb2.HealthCheckResponse.FromString,
|
42
|
+
_registered_method=True)
|
43
|
+
|
44
|
+
|
45
|
+
class HealthServiceServicer(object):
|
46
|
+
"""HealthService is a service that implements health check.
|
47
|
+
"""
|
48
|
+
|
49
|
+
def Check(self, request, context):
|
50
|
+
"""Missing associated documentation comment in .proto file."""
|
51
|
+
context.set_code(grpc.StatusCode.UNIMPLEMENTED)
|
52
|
+
context.set_details('Method not implemented!')
|
53
|
+
raise NotImplementedError('Method not implemented!')
|
54
|
+
|
55
|
+
|
56
|
+
def add_HealthServiceServicer_to_server(servicer, server):
|
57
|
+
rpc_method_handlers = {
|
58
|
+
'Check': grpc.unary_unary_rpc_method_handler(
|
59
|
+
servicer.Check,
|
60
|
+
request_deserializer=divi_dot_proto_dot_core_dot_health_dot_v1_dot_health__service__pb2.HealthCheckRequest.FromString,
|
61
|
+
response_serializer=divi_dot_proto_dot_core_dot_health_dot_v1_dot_health__service__pb2.HealthCheckResponse.SerializeToString,
|
62
|
+
),
|
63
|
+
}
|
64
|
+
generic_handler = grpc.method_handlers_generic_handler(
|
65
|
+
'divi.proto.core.health.v1.HealthService', rpc_method_handlers)
|
66
|
+
server.add_generic_rpc_handlers((generic_handler,))
|
67
|
+
server.add_registered_method_handlers('divi.proto.core.health.v1.HealthService', rpc_method_handlers)
|
68
|
+
|
69
|
+
|
70
|
+
# This class is part of an EXPERIMENTAL API.
|
71
|
+
class HealthService(object):
|
72
|
+
"""HealthService is a service that implements health check.
|
73
|
+
"""
|
74
|
+
|
75
|
+
@staticmethod
|
76
|
+
def Check(request,
|
77
|
+
target,
|
78
|
+
options=(),
|
79
|
+
channel_credentials=None,
|
80
|
+
call_credentials=None,
|
81
|
+
insecure=False,
|
82
|
+
compression=None,
|
83
|
+
wait_for_ready=None,
|
84
|
+
timeout=None,
|
85
|
+
metadata=None):
|
86
|
+
return grpc.experimental.unary_unary(
|
87
|
+
request,
|
88
|
+
target,
|
89
|
+
'/divi.proto.core.health.v1.HealthService/Check',
|
90
|
+
divi_dot_proto_dot_core_dot_health_dot_v1_dot_health__service__pb2.HealthCheckRequest.SerializeToString,
|
91
|
+
divi_dot_proto_dot_core_dot_health_dot_v1_dot_health__service__pb2.HealthCheckResponse.FromString,
|
92
|
+
options,
|
93
|
+
channel_credentials,
|
94
|
+
insecure,
|
95
|
+
call_credentials,
|
96
|
+
compression,
|
97
|
+
wait_for_ready,
|
98
|
+
timeout,
|
99
|
+
metadata,
|
100
|
+
_registered_method=True)
|
@@ -0,0 +1,26 @@
|
|
1
|
+
syntax = "proto3";
|
2
|
+
|
3
|
+
package divi.proto.metric.v1;
|
4
|
+
|
5
|
+
import "divi/proto/common/v1/common.proto";
|
6
|
+
|
7
|
+
option go_package = "services/pb";
|
8
|
+
|
9
|
+
message ScopeMetrics {
|
10
|
+
// A list of spans that originate from a resource.
|
11
|
+
repeated Metric metrics = 2;
|
12
|
+
}
|
13
|
+
|
14
|
+
message Metric {
|
15
|
+
// The name of the metric.
|
16
|
+
string name = 1;
|
17
|
+
|
18
|
+
// The description of the metric.
|
19
|
+
string description = 2;
|
20
|
+
|
21
|
+
// The data of the metric.
|
22
|
+
divi.proto.common.v1.AnyValue data = 3;
|
23
|
+
|
24
|
+
// The metadata is a set of attributes that describe the span.
|
25
|
+
repeated divi.proto.common.v1.KeyValue metadata = 4;
|
26
|
+
}
|
@@ -0,0 +1,40 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
# Generated by the protocol buffer compiler. DO NOT EDIT!
|
3
|
+
# NO CHECKED-IN PROTOBUF GENCODE
|
4
|
+
# source: divi/proto/metric/v1/metric.proto
|
5
|
+
# Protobuf Python Version: 5.29.0
|
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
|
+
5,
|
15
|
+
29,
|
16
|
+
0,
|
17
|
+
'',
|
18
|
+
'divi/proto/metric/v1/metric.proto'
|
19
|
+
)
|
20
|
+
# @@protoc_insertion_point(imports)
|
21
|
+
|
22
|
+
_sym_db = _symbol_database.Default()
|
23
|
+
|
24
|
+
|
25
|
+
from divi.proto.common.v1 import common_pb2 as divi_dot_proto_dot_common_dot_v1_dot_common__pb2
|
26
|
+
|
27
|
+
|
28
|
+
DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n!divi/proto/metric/v1/metric.proto\x12\x14\x64ivi.proto.metric.v1\x1a!divi/proto/common/v1/common.proto\"=\n\x0cScopeMetrics\x12-\n\x07metrics\x18\x02 \x03(\x0b\x32\x1c.divi.proto.metric.v1.Metric\"\x8b\x01\n\x06Metric\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x13\n\x0b\x64\x65scription\x18\x02 \x01(\t\x12,\n\x04\x64\x61ta\x18\x03 \x01(\x0b\x32\x1e.divi.proto.common.v1.AnyValue\x12\x30\n\x08metadata\x18\x04 \x03(\x0b\x32\x1e.divi.proto.common.v1.KeyValueB\rZ\x0bservices/pbb\x06proto3')
|
29
|
+
|
30
|
+
_globals = globals()
|
31
|
+
_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals)
|
32
|
+
_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'divi.proto.metric.v1.metric_pb2', _globals)
|
33
|
+
if not _descriptor._USE_C_DESCRIPTORS:
|
34
|
+
_globals['DESCRIPTOR']._loaded_options = None
|
35
|
+
_globals['DESCRIPTOR']._serialized_options = b'Z\013services/pb'
|
36
|
+
_globals['_SCOPEMETRICS']._serialized_start=94
|
37
|
+
_globals['_SCOPEMETRICS']._serialized_end=155
|
38
|
+
_globals['_METRIC']._serialized_start=158
|
39
|
+
_globals['_METRIC']._serialized_end=297
|
40
|
+
# @@protoc_insertion_point(module_scope)
|
@@ -0,0 +1,25 @@
|
|
1
|
+
from divi.proto.common.v1 import common_pb2 as _common_pb2
|
2
|
+
from google.protobuf.internal import containers as _containers
|
3
|
+
from google.protobuf import descriptor as _descriptor
|
4
|
+
from google.protobuf import message as _message
|
5
|
+
from typing import ClassVar as _ClassVar, Iterable as _Iterable, Mapping as _Mapping, Optional as _Optional, Union as _Union
|
6
|
+
|
7
|
+
DESCRIPTOR: _descriptor.FileDescriptor
|
8
|
+
|
9
|
+
class ScopeMetrics(_message.Message):
|
10
|
+
__slots__ = ("metrics",)
|
11
|
+
METRICS_FIELD_NUMBER: _ClassVar[int]
|
12
|
+
metrics: _containers.RepeatedCompositeFieldContainer[Metric]
|
13
|
+
def __init__(self, metrics: _Optional[_Iterable[_Union[Metric, _Mapping]]] = ...) -> None: ...
|
14
|
+
|
15
|
+
class Metric(_message.Message):
|
16
|
+
__slots__ = ("name", "description", "data", "metadata")
|
17
|
+
NAME_FIELD_NUMBER: _ClassVar[int]
|
18
|
+
DESCRIPTION_FIELD_NUMBER: _ClassVar[int]
|
19
|
+
DATA_FIELD_NUMBER: _ClassVar[int]
|
20
|
+
METADATA_FIELD_NUMBER: _ClassVar[int]
|
21
|
+
name: str
|
22
|
+
description: str
|
23
|
+
data: _common_pb2.AnyValue
|
24
|
+
metadata: _containers.RepeatedCompositeFieldContainer[_common_pb2.KeyValue]
|
25
|
+
def __init__(self, name: _Optional[str] = ..., description: _Optional[str] = ..., data: _Optional[_Union[_common_pb2.AnyValue, _Mapping]] = ..., metadata: _Optional[_Iterable[_Union[_common_pb2.KeyValue, _Mapping]]] = ...) -> None: ...
|
@@ -0,0 +1,50 @@
|
|
1
|
+
syntax = "proto3";
|
2
|
+
|
3
|
+
package divi.proto.trace.v1;
|
4
|
+
|
5
|
+
import "divi/proto/common/v1/common.proto";
|
6
|
+
|
7
|
+
option go_package = "services/pb";
|
8
|
+
|
9
|
+
message ScopeSpans {
|
10
|
+
// A list of spans that originate from a resource.
|
11
|
+
repeated Span spans = 2;
|
12
|
+
}
|
13
|
+
|
14
|
+
message Span {
|
15
|
+
// The trace_id is a unique identifier that represents a trace. It is a 16-byte array.
|
16
|
+
bytes trace_id = 1;
|
17
|
+
|
18
|
+
// The span_id is a unique identifier that represents a span. It is an 8-byte array.
|
19
|
+
bytes span_id = 2;
|
20
|
+
|
21
|
+
// The parent_span_id is the span_id of the parent span. It is an 8-byte array.
|
22
|
+
bytes parent_span_id = 3;
|
23
|
+
|
24
|
+
// The name of the span.
|
25
|
+
string name = 4;
|
26
|
+
|
27
|
+
// SpanKind is the type of the span.
|
28
|
+
enum SpanKind {
|
29
|
+
// Function represents a function call.
|
30
|
+
SPAN_KIND_FUNCTION = 0;
|
31
|
+
|
32
|
+
// LLM represents a llm api call.
|
33
|
+
SPAN_KIND_LLM = 1;
|
34
|
+
|
35
|
+
// EVALUATION represents an evaluation.
|
36
|
+
SPAN_KIND_EVALUATION = 2;
|
37
|
+
}
|
38
|
+
|
39
|
+
// The kind of the span.
|
40
|
+
SpanKind kind = 5;
|
41
|
+
|
42
|
+
// The start_time_unix_nano is the start time of the span in Unix nanoseconds.
|
43
|
+
fixed64 start_time_unix_nano = 6;
|
44
|
+
|
45
|
+
// The end_time_unix_nano is the end time of the span in Unix nanoseconds.
|
46
|
+
fixed64 end_time_unix_nano = 7;
|
47
|
+
|
48
|
+
// The metadata is a set of attributes that describe the span.
|
49
|
+
repeated divi.proto.common.v1.KeyValue metadata = 8;
|
50
|
+
}
|
@@ -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: divi/proto/trace/v1/trace.proto
|
5
|
+
# Protobuf Python Version: 5.29.0
|
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
|
+
5,
|
15
|
+
29,
|
16
|
+
0,
|
17
|
+
'',
|
18
|
+
'divi/proto/trace/v1/trace.proto'
|
19
|
+
)
|
20
|
+
# @@protoc_insertion_point(imports)
|
21
|
+
|
22
|
+
_sym_db = _symbol_database.Default()
|
23
|
+
|
24
|
+
|
25
|
+
from divi.proto.common.v1 import common_pb2 as divi_dot_proto_dot_common_dot_v1_dot_common__pb2
|
26
|
+
|
27
|
+
|
28
|
+
DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x1f\x64ivi/proto/trace/v1/trace.proto\x12\x13\x64ivi.proto.trace.v1\x1a!divi/proto/common/v1/common.proto\"6\n\nScopeSpans\x12(\n\x05spans\x18\x02 \x03(\x0b\x32\x19.divi.proto.trace.v1.Span\"\xbe\x02\n\x04Span\x12\x10\n\x08trace_id\x18\x01 \x01(\x0c\x12\x0f\n\x07span_id\x18\x02 \x01(\x0c\x12\x16\n\x0eparent_span_id\x18\x03 \x01(\x0c\x12\x0c\n\x04name\x18\x04 \x01(\t\x12\x30\n\x04kind\x18\x05 \x01(\x0e\x32\".divi.proto.trace.v1.Span.SpanKind\x12\x1c\n\x14start_time_unix_nano\x18\x06 \x01(\x06\x12\x1a\n\x12\x65nd_time_unix_nano\x18\x07 \x01(\x06\x12\x30\n\x08metadata\x18\x08 \x03(\x0b\x32\x1e.divi.proto.common.v1.KeyValue\"O\n\x08SpanKind\x12\x16\n\x12SPAN_KIND_FUNCTION\x10\x00\x12\x11\n\rSPAN_KIND_LLM\x10\x01\x12\x18\n\x14SPAN_KIND_EVALUATION\x10\x02\x42\rZ\x0bservices/pbb\x06proto3')
|
29
|
+
|
30
|
+
_globals = globals()
|
31
|
+
_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals)
|
32
|
+
_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'divi.proto.trace.v1.trace_pb2', _globals)
|
33
|
+
if not _descriptor._USE_C_DESCRIPTORS:
|
34
|
+
_globals['DESCRIPTOR']._loaded_options = None
|
35
|
+
_globals['DESCRIPTOR']._serialized_options = b'Z\013services/pb'
|
36
|
+
_globals['_SCOPESPANS']._serialized_start=91
|
37
|
+
_globals['_SCOPESPANS']._serialized_end=145
|
38
|
+
_globals['_SPAN']._serialized_start=148
|
39
|
+
_globals['_SPAN']._serialized_end=466
|
40
|
+
_globals['_SPAN_SPANKIND']._serialized_start=387
|
41
|
+
_globals['_SPAN_SPANKIND']._serialized_end=466
|
42
|
+
# @@protoc_insertion_point(module_scope)
|
@@ -0,0 +1,42 @@
|
|
1
|
+
from divi.proto.common.v1 import common_pb2 as _common_pb2
|
2
|
+
from google.protobuf.internal import containers as _containers
|
3
|
+
from google.protobuf.internal import enum_type_wrapper as _enum_type_wrapper
|
4
|
+
from google.protobuf import descriptor as _descriptor
|
5
|
+
from google.protobuf import message as _message
|
6
|
+
from typing import ClassVar as _ClassVar, Iterable as _Iterable, Mapping as _Mapping, Optional as _Optional, Union as _Union
|
7
|
+
|
8
|
+
DESCRIPTOR: _descriptor.FileDescriptor
|
9
|
+
|
10
|
+
class ScopeSpans(_message.Message):
|
11
|
+
__slots__ = ("spans",)
|
12
|
+
SPANS_FIELD_NUMBER: _ClassVar[int]
|
13
|
+
spans: _containers.RepeatedCompositeFieldContainer[Span]
|
14
|
+
def __init__(self, spans: _Optional[_Iterable[_Union[Span, _Mapping]]] = ...) -> None: ...
|
15
|
+
|
16
|
+
class Span(_message.Message):
|
17
|
+
__slots__ = ("trace_id", "span_id", "parent_span_id", "name", "kind", "start_time_unix_nano", "end_time_unix_nano", "metadata")
|
18
|
+
class SpanKind(int, metaclass=_enum_type_wrapper.EnumTypeWrapper):
|
19
|
+
__slots__ = ()
|
20
|
+
SPAN_KIND_FUNCTION: _ClassVar[Span.SpanKind]
|
21
|
+
SPAN_KIND_LLM: _ClassVar[Span.SpanKind]
|
22
|
+
SPAN_KIND_EVALUATION: _ClassVar[Span.SpanKind]
|
23
|
+
SPAN_KIND_FUNCTION: Span.SpanKind
|
24
|
+
SPAN_KIND_LLM: Span.SpanKind
|
25
|
+
SPAN_KIND_EVALUATION: Span.SpanKind
|
26
|
+
TRACE_ID_FIELD_NUMBER: _ClassVar[int]
|
27
|
+
SPAN_ID_FIELD_NUMBER: _ClassVar[int]
|
28
|
+
PARENT_SPAN_ID_FIELD_NUMBER: _ClassVar[int]
|
29
|
+
NAME_FIELD_NUMBER: _ClassVar[int]
|
30
|
+
KIND_FIELD_NUMBER: _ClassVar[int]
|
31
|
+
START_TIME_UNIX_NANO_FIELD_NUMBER: _ClassVar[int]
|
32
|
+
END_TIME_UNIX_NANO_FIELD_NUMBER: _ClassVar[int]
|
33
|
+
METADATA_FIELD_NUMBER: _ClassVar[int]
|
34
|
+
trace_id: bytes
|
35
|
+
span_id: bytes
|
36
|
+
parent_span_id: bytes
|
37
|
+
name: str
|
38
|
+
kind: Span.SpanKind
|
39
|
+
start_time_unix_nano: int
|
40
|
+
end_time_unix_nano: int
|
41
|
+
metadata: _containers.RepeatedCompositeFieldContainer[_common_pb2.KeyValue]
|
42
|
+
def __init__(self, trace_id: _Optional[bytes] = ..., span_id: _Optional[bytes] = ..., parent_span_id: _Optional[bytes] = ..., name: _Optional[str] = ..., kind: _Optional[_Union[Span.SpanKind, str]] = ..., start_time_unix_nano: _Optional[int] = ..., end_time_unix_nano: _Optional[int] = ..., metadata: _Optional[_Iterable[_Union[_common_pb2.KeyValue, _Mapping]]] = ...) -> None: ...
|
@@ -0,0 +1,13 @@
|
|
1
|
+
from divi.services.auth.tokman import Token
|
2
|
+
from divi.services.service import Service
|
3
|
+
|
4
|
+
|
5
|
+
class Auth(Service):
|
6
|
+
def __init__(self, api_key: str, host="localhost", port=3000):
|
7
|
+
super().__init__(host, port)
|
8
|
+
self.api_key = api_key
|
9
|
+
self.token = Token(self)
|
10
|
+
|
11
|
+
def auth_with_api_key(self) -> str:
|
12
|
+
"""Get the token with the API key."""
|
13
|
+
return self.post("/api/auth/api_key", payload={"api_key": self.api_key})
|
@@ -0,0 +1,22 @@
|
|
1
|
+
import os
|
2
|
+
from typing import Optional
|
3
|
+
|
4
|
+
from divi.services.auth import Auth
|
5
|
+
|
6
|
+
DIVI_API_KEY = "DIVI_API_KEY"
|
7
|
+
DIVI_AUTH_HOST = "DIVI_AUTH_HOST"
|
8
|
+
DIVI_AUTH_PORT = "DIVI_AUTH_PORT"
|
9
|
+
|
10
|
+
|
11
|
+
def init_auth(
|
12
|
+
host: Optional[str] = None,
|
13
|
+
port: Optional[int] = None,
|
14
|
+
api_key: Optional[str] = None,
|
15
|
+
) -> Auth:
|
16
|
+
host = host if host else os.getenv(DIVI_AUTH_HOST, "auth.divine-agent.com")
|
17
|
+
port = port if port else int(os.getenv(DIVI_AUTH_PORT, 80))
|
18
|
+
key = api_key if api_key else os.getenv(DIVI_API_KEY)
|
19
|
+
if not key:
|
20
|
+
raise ValueError("DIVI_API_KEY is required")
|
21
|
+
|
22
|
+
return Auth(api_key=key, host=host, port=port)
|
@@ -0,0 +1,42 @@
|
|
1
|
+
import time
|
2
|
+
from weakref import ref
|
3
|
+
|
4
|
+
import jwt
|
5
|
+
|
6
|
+
|
7
|
+
class Token:
|
8
|
+
"""JWT Manager Class."""
|
9
|
+
|
10
|
+
def __init__(self, auth) -> None:
|
11
|
+
self.auth = ref(auth)
|
12
|
+
self.claims: dict = {}
|
13
|
+
self.__token: str = ""
|
14
|
+
|
15
|
+
def __str__(self) -> str:
|
16
|
+
return self.token
|
17
|
+
|
18
|
+
@property
|
19
|
+
def exp(self) -> int:
|
20
|
+
"""Return the expiration time."""
|
21
|
+
return self.claims.get("exp", 0)
|
22
|
+
|
23
|
+
@property
|
24
|
+
def token(self) -> str:
|
25
|
+
"""Return the token string."""
|
26
|
+
# If the token is expired, get a new one
|
27
|
+
if not self.__token or self.exp - time.time() < 3600:
|
28
|
+
self._init_token()
|
29
|
+
return self.__token
|
30
|
+
|
31
|
+
def _init_token(self):
|
32
|
+
"""Initialize the token."""
|
33
|
+
auth = self.auth()
|
34
|
+
if not auth:
|
35
|
+
raise ValueError("Auth object is not available")
|
36
|
+
self.__token = auth.auth_with_api_key()
|
37
|
+
self.claims = _decode_token(self.__token)
|
38
|
+
|
39
|
+
|
40
|
+
def _decode_token(token: str) -> dict:
|
41
|
+
"""Decode the token payload."""
|
42
|
+
return jwt.decode(token, options={"verify_signature": False})
|
@@ -0,0 +1,35 @@
|
|
1
|
+
from subprocess import Popen
|
2
|
+
from typing import Callable, List, Optional
|
3
|
+
|
4
|
+
import grpc
|
5
|
+
|
6
|
+
import divi
|
7
|
+
from divi.proto.core.health.v1.health_service_pb2 import HealthCheckRequest
|
8
|
+
from divi.proto.core.health.v1.health_service_pb2_grpc import HealthServiceStub
|
9
|
+
from divi.services.service import Service
|
10
|
+
|
11
|
+
|
12
|
+
class Core(Service):
|
13
|
+
"""Core Runtime Class."""
|
14
|
+
|
15
|
+
def __init__(self, host="localhost", port=50051) -> None:
|
16
|
+
super().__init__(host, port)
|
17
|
+
self.process: Optional[Popen] = None
|
18
|
+
self.hooks: List[Callable[[], None]] = []
|
19
|
+
|
20
|
+
def check_health(self) -> bool:
|
21
|
+
"""Check the health of the service."""
|
22
|
+
with grpc.insecure_channel(self.target) as channel:
|
23
|
+
stub = HealthServiceStub(channel)
|
24
|
+
response, call = stub.Check.with_call(
|
25
|
+
HealthCheckRequest(version=divi.__version__),
|
26
|
+
# Note: ((),) notice the `,` at the end of the tuple
|
27
|
+
metadata=(("version", divi.__version__),),
|
28
|
+
)
|
29
|
+
print(f"Health check: {response.message}")
|
30
|
+
for key, value in call.trailing_metadata():
|
31
|
+
print(
|
32
|
+
"python client received trailing metadata: key=%s value=%s"
|
33
|
+
% (key, value)
|
34
|
+
)
|
35
|
+
return response.status
|
@@ -0,0 +1,70 @@
|
|
1
|
+
import atexit
|
2
|
+
import socket
|
3
|
+
import subprocess
|
4
|
+
import time
|
5
|
+
|
6
|
+
import grpc
|
7
|
+
|
8
|
+
from divi.services.core import Core
|
9
|
+
from divi.utils import get_server_path
|
10
|
+
|
11
|
+
|
12
|
+
def init_core(host="localhost", port=50051) -> Core:
|
13
|
+
core = Core(host=host, port=port)
|
14
|
+
_start_server(core)
|
15
|
+
return core
|
16
|
+
|
17
|
+
|
18
|
+
def _start_server(core: Core):
|
19
|
+
"""Start the backend server."""
|
20
|
+
# start the server
|
21
|
+
bin_path = get_server_path()
|
22
|
+
command = [bin_path, "-port", str(core.port)]
|
23
|
+
core.process = subprocess.Popen(command)
|
24
|
+
|
25
|
+
# Wait for the port to be open
|
26
|
+
if not _wait_for_port(core.host, core.port, 10):
|
27
|
+
core.process.terminate()
|
28
|
+
raise RuntimeError("Service failed to start: port not open")
|
29
|
+
|
30
|
+
# Check if the gRPC channel is ready
|
31
|
+
channel = grpc.insecure_channel(core.target)
|
32
|
+
try:
|
33
|
+
grpc.channel_ready_future(channel).result(timeout=10)
|
34
|
+
except grpc.FutureTimeoutError:
|
35
|
+
core.process.terminate()
|
36
|
+
raise RuntimeError("gRPC channel not ready")
|
37
|
+
finally:
|
38
|
+
channel.close()
|
39
|
+
|
40
|
+
core.hooks.append(core.process.terminate)
|
41
|
+
atexit.register(core.process.terminate)
|
42
|
+
|
43
|
+
# Health check
|
44
|
+
status = core.check_health()
|
45
|
+
if not status:
|
46
|
+
raise RuntimeError("Service failed health check")
|
47
|
+
|
48
|
+
|
49
|
+
def _wait_for_port(host, port, timeout_seconds):
|
50
|
+
"""Wait until the specified port is open."""
|
51
|
+
start_time = time.time()
|
52
|
+
while time.time() - start_time < timeout_seconds:
|
53
|
+
if _is_port_open(host, port):
|
54
|
+
return True
|
55
|
+
time.sleep(0.1)
|
56
|
+
return False
|
57
|
+
|
58
|
+
|
59
|
+
def _is_port_open(host, port):
|
60
|
+
"""Check if the given host and port are open."""
|
61
|
+
try:
|
62
|
+
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as sock:
|
63
|
+
result = sock.connect_ex((host, port))
|
64
|
+
if result == 0:
|
65
|
+
return True
|
66
|
+
else:
|
67
|
+
return False
|
68
|
+
except Exception as e:
|
69
|
+
print(f"Error checking port: {e}")
|
70
|
+
return False
|