divi 0.0.1.dev21__py3-none-any.whl → 0.0.1.dev23__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 +1 -1
- divi/decorators/obs_openai.py +0 -1
- divi/decorators/observable.py +11 -32
- divi/services/datapark/datapark.py +10 -4
- divi/session/session.py +3 -3
- divi/session/setup.py +9 -26
- divi/signals/trace/trace.py +18 -18
- {divi-0.0.1.dev21.dist-info → divi-0.0.1.dev23.dist-info}/METADATA +1 -1
- {divi-0.0.1.dev21.dist-info → divi-0.0.1.dev23.dist-info}/RECORD +11 -11
- {divi-0.0.1.dev21.dist-info → divi-0.0.1.dev23.dist-info}/WHEEL +0 -0
- {divi-0.0.1.dev21.dist-info → divi-0.0.1.dev23.dist-info}/licenses/LICENSE +0 -0
divi/__init__.py
CHANGED
divi/decorators/obs_openai.py
CHANGED
@@ -18,7 +18,6 @@ def _get_observable_create(create: Callable) -> Callable:
|
|
18
18
|
return decorator(create)(*args, stream=stream, **kwargs)
|
19
19
|
|
20
20
|
# TODO Async Observable Create
|
21
|
-
print("Is async", is_async(create))
|
22
21
|
return observable_create if not is_async(create) else create
|
23
22
|
|
24
23
|
|
divi/decorators/observable.py
CHANGED
@@ -85,7 +85,11 @@ def observable(
|
|
85
85
|
# recover parent context
|
86
86
|
_SESSION_EXTRA.reset(token)
|
87
87
|
|
88
|
-
#
|
88
|
+
# get the trace to collect data
|
89
|
+
trace = session_extra.get("trace")
|
90
|
+
if not trace:
|
91
|
+
raise ValueError("Trace not found in session_extra")
|
92
|
+
# TODO: collect inputs and outputs for SPAN_KIND_FUNCTION
|
89
93
|
inputs = extract_flattened_inputs(func, *args, **kwargs)
|
90
94
|
# create the span if it is the root span
|
91
95
|
if divi._datapark and span.trace_id:
|
@@ -94,43 +98,18 @@ def observable(
|
|
94
98
|
)
|
95
99
|
# end the trace if it is the root span
|
96
100
|
if divi._datapark and not span.parent_span_id:
|
97
|
-
trace
|
98
|
-
if trace:
|
99
|
-
trace.end()
|
100
|
-
divi._datapark.upsert_traces(
|
101
|
-
session_id=trace.session_id, traces=[trace.signal]
|
102
|
-
)
|
101
|
+
trace.end()
|
103
102
|
# create the chat completion if it is a chat completion
|
104
103
|
if divi._datapark and isinstance(result, ChatCompletion):
|
105
104
|
divi._datapark.create_chat_completion(
|
106
|
-
span_id=span.span_id,
|
105
|
+
span_id=span.span_id,
|
106
|
+
trace_id=trace.trace_id,
|
107
|
+
inputs=inputs,
|
108
|
+
completion=result,
|
107
109
|
)
|
108
|
-
return result
|
109
110
|
|
110
|
-
|
111
|
-
def generator_wrapper(
|
112
|
-
*args, session_extra: Optional[SessionExtra] = None, **kwargs
|
113
|
-
):
|
114
|
-
span = Span(
|
115
|
-
kind=kind, name=name or func.__name__, metadata=metadata
|
116
|
-
)
|
117
|
-
session_extra = setup(span, _SESSION_EXTRA.get() or session_extra)
|
118
|
-
# set current context
|
119
|
-
token = _SESSION_EXTRA.set(session_extra)
|
120
|
-
# execute the function
|
121
|
-
results: List[Any] = []
|
122
|
-
span.start()
|
123
|
-
for item in func(*args, **kwargs):
|
124
|
-
results.append(item)
|
125
|
-
yield item
|
126
|
-
span.end()
|
127
|
-
|
128
|
-
# recover parent context
|
129
|
-
_SESSION_EXTRA.reset(token)
|
130
|
-
# TODO: collect results
|
111
|
+
return result
|
131
112
|
|
132
|
-
if inspect.isgeneratorfunction(func):
|
133
|
-
return generator_wrapper
|
134
113
|
return wrapper
|
135
114
|
|
136
115
|
# Function Decorator
|
@@ -1,16 +1,16 @@
|
|
1
|
-
from typing import Any, Dict
|
2
|
-
from typing_extensions import Mapping
|
1
|
+
from typing import Any, Dict
|
3
2
|
|
4
3
|
from google.protobuf.json_format import MessageToDict
|
4
|
+
from openai import NotGiven
|
5
5
|
from openai.types.chat import ChatCompletion
|
6
6
|
from pydantic import UUID4
|
7
|
+
from typing_extensions import Mapping
|
7
8
|
|
8
9
|
import divi
|
9
10
|
from divi.proto.trace.v1.trace_pb2 import ScopeSpans
|
10
11
|
from divi.services.service import Service
|
11
12
|
from divi.session.session import SessionSignal
|
12
13
|
from divi.signals.trace.trace import TraceSignal
|
13
|
-
from openai import NotGiven
|
14
14
|
|
15
15
|
|
16
16
|
class DataPark(Service):
|
@@ -33,7 +33,11 @@ class DataPark(Service):
|
|
33
33
|
if not isinstance(obj, Mapping):
|
34
34
|
return obj
|
35
35
|
|
36
|
-
return {
|
36
|
+
return {
|
37
|
+
key: value
|
38
|
+
for key, value in obj.items()
|
39
|
+
if not isinstance(value, NotGiven)
|
40
|
+
}
|
37
41
|
|
38
42
|
def create_session(self, session: SessionSignal) -> None:
|
39
43
|
self.post("/api/session/", payload=session)
|
@@ -49,6 +53,7 @@ class DataPark(Service):
|
|
49
53
|
def create_chat_completion(
|
50
54
|
self,
|
51
55
|
span_id: bytes,
|
56
|
+
trace_id: UUID4,
|
52
57
|
inputs: Dict[str, Any],
|
53
58
|
completion: ChatCompletion,
|
54
59
|
) -> None:
|
@@ -61,6 +66,7 @@ class DataPark(Service):
|
|
61
66
|
},
|
62
67
|
"/api/v1/chat/completions": {
|
63
68
|
"span_id": hex_span_id,
|
69
|
+
"trace_id": str(trace_id),
|
64
70
|
"data": completion.model_dump(),
|
65
71
|
},
|
66
72
|
}
|
divi/session/session.py
CHANGED
@@ -9,13 +9,13 @@ class SessionExtra(TypedDict, total=False):
|
|
9
9
|
|
10
10
|
session_name: Optional[str]
|
11
11
|
"""Name of the session"""
|
12
|
-
trace:
|
13
|
-
"""Trace
|
12
|
+
trace: Trace
|
13
|
+
"""Trace in session"""
|
14
14
|
parent_span_id: Optional[bytes]
|
15
15
|
"""Parent Span ID fixed string(8)"""
|
16
16
|
|
17
17
|
|
18
|
-
class SessionSignal(TypedDict
|
18
|
+
class SessionSignal(TypedDict):
|
19
19
|
"""Session request"""
|
20
20
|
|
21
21
|
id: str
|
divi/session/setup.py
CHANGED
@@ -1,3 +1,4 @@
|
|
1
|
+
from typing_extensions import Optional
|
1
2
|
import divi
|
2
3
|
from divi.services import init as init_services
|
3
4
|
from divi.session import Session, SessionExtra
|
@@ -5,10 +6,10 @@ from divi.signals.trace import Span
|
|
5
6
|
from divi.signals.trace.trace import Trace
|
6
7
|
|
7
8
|
|
8
|
-
def
|
9
|
+
def init_session(name: Optional[str]=None) -> Session:
|
9
10
|
"""init initializes the services and the Run"""
|
10
11
|
init_services()
|
11
|
-
session = Session(name=
|
12
|
+
session = Session(name=name)
|
12
13
|
if divi._datapark:
|
13
14
|
divi._datapark.create_session(session.signal)
|
14
15
|
return session
|
@@ -24,39 +25,21 @@ def setup(
|
|
24
25
|
span (Span): Span instance
|
25
26
|
session_extra (SessionExtra | None): Extra information from user input
|
26
27
|
"""
|
27
|
-
# TOOD: merge run_extra input by user with the one from the context
|
28
|
-
# temp solution: Priority: run_extra_context.get() > run_extra
|
29
28
|
session_extra = session_extra or SessionExtra()
|
30
29
|
|
31
30
|
# init the session if not already initialized
|
32
31
|
if not divi._session:
|
33
|
-
divi._session =
|
32
|
+
divi._session = init_session(name=session_extra.get('session_name') or span.name)
|
34
33
|
|
35
34
|
# setup trace
|
36
|
-
|
37
|
-
trace = session_extra.get("trace")
|
35
|
+
trace = session_extra.get("trace") or Trace(divi._session.id, span.name)
|
38
36
|
parent_span_id = session_extra.get("parent_span_id")
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
trace.start()
|
44
|
-
span._as_root(trace.trace_id)
|
45
|
-
# create the trace
|
46
|
-
if divi._datapark:
|
47
|
-
divi._datapark.upsert_traces(
|
48
|
-
session_id=divi._session.id, traces=[trace.signal]
|
49
|
-
)
|
50
|
-
|
51
|
-
# update the session_extra with the current span
|
52
|
-
# session_extra["trace_id"] = span.trace_id
|
53
|
-
# session_extra["parent_span_id"] = span.span_id
|
54
|
-
session_extra = SessionExtra(
|
37
|
+
span._add_node(trace.trace_id, parent_span_id)
|
38
|
+
|
39
|
+
# update the session_extra with the current trace and span
|
40
|
+
return SessionExtra(
|
55
41
|
session_name=divi._session.name,
|
56
42
|
trace=trace,
|
57
43
|
# set the parent_span_id to the current span_id
|
58
44
|
parent_span_id=span.span_id,
|
59
45
|
)
|
60
|
-
|
61
|
-
# offer end hook to collect data at whe end of the span ?
|
62
|
-
return session_extra
|
divi/signals/trace/trace.py
CHANGED
@@ -7,6 +7,7 @@ from uuid import uuid4
|
|
7
7
|
from pydantic import UUID4
|
8
8
|
from typing_extensions import TypedDict
|
9
9
|
|
10
|
+
import divi
|
10
11
|
from divi.proto.common.v1.common_pb2 import KeyValue
|
11
12
|
from divi.proto.trace.v1.trace_pb2 import Span as SpanProto
|
12
13
|
|
@@ -29,15 +30,19 @@ class TraceSignal(TypedDict, total=False):
|
|
29
30
|
"""Start time in iso format"""
|
30
31
|
end_time: NullTime
|
31
32
|
"""End time in iso format"""
|
33
|
+
name: Optional[str]
|
32
34
|
|
33
35
|
|
34
36
|
class Trace:
|
35
|
-
def __init__(self, session_id: UUID4):
|
37
|
+
def __init__(self, session_id: UUID4, name: Optional[str] = None):
|
36
38
|
self.trace_id: UUID4 = uuid4()
|
37
39
|
self.start_time: str | None = None
|
38
40
|
self.end_time: str | None = None
|
41
|
+
self.name: Optional[str] = name
|
39
42
|
self.session_id: UUID4 = session_id
|
40
43
|
|
44
|
+
self.start()
|
45
|
+
|
41
46
|
@property
|
42
47
|
def signal(self) -> TraceSignal:
|
43
48
|
if self.start_time is None:
|
@@ -45,6 +50,7 @@ class Trace:
|
|
45
50
|
signal = TraceSignal(
|
46
51
|
id=str(self.trace_id),
|
47
52
|
start_time=self.start_time,
|
53
|
+
name=self.name,
|
48
54
|
)
|
49
55
|
if self.end_time is not None:
|
50
56
|
signal["end_time"] = NullTime(
|
@@ -60,12 +66,21 @@ class Trace:
|
|
60
66
|
def start(self):
|
61
67
|
"""Start the trace by recording the current time in nanoseconds."""
|
62
68
|
self.start_time = datetime.now(UTC).isoformat()
|
69
|
+
self.upsert_trace()
|
63
70
|
|
64
71
|
def end(self):
|
65
72
|
"""End the trace by recording the end time in nanoseconds."""
|
66
73
|
if self.start_time is None:
|
67
74
|
raise ValueError("Span must be started before ending.")
|
68
75
|
self.end_time = datetime.now(UTC).isoformat()
|
76
|
+
self.upsert_trace()
|
77
|
+
|
78
|
+
def upsert_trace(self):
|
79
|
+
"""Upsert trace with datapark."""
|
80
|
+
if divi._datapark:
|
81
|
+
divi._datapark.upsert_traces(
|
82
|
+
session_id=self.session_id, traces=[self.signal]
|
83
|
+
)
|
69
84
|
|
70
85
|
|
71
86
|
class Span:
|
@@ -102,7 +117,6 @@ class Span:
|
|
102
117
|
trace_id=self.trace_id.bytes if self.trace_id else None,
|
103
118
|
parent_span_id=self.parent_span_id,
|
104
119
|
)
|
105
|
-
print(self.kind)
|
106
120
|
signal.metadata.extend(
|
107
121
|
KeyValue(key=k, value=v)
|
108
122
|
for k, v in (self.metadata or dict()).items()
|
@@ -131,21 +145,7 @@ class Span:
|
|
131
145
|
raise ValueError("Span must be started before ending.")
|
132
146
|
self.end_time_unix_nano = time.time_ns()
|
133
147
|
|
134
|
-
def
|
135
|
-
"""
|
136
|
-
self.trace_id = trace_id
|
137
|
-
print("as root")
|
138
|
-
print(f"name: {self.name}")
|
139
|
-
print(f"trace_id: {self.trace_id}")
|
140
|
-
print(f"span_id: {self.span_id}")
|
141
|
-
|
142
|
-
def _add_parent(self, trace_id: UUID4, parent_id: bytes):
|
143
|
-
"""Set the parent span ID."""
|
148
|
+
def _add_node(self, trace_id: UUID4, parent_id: Optional[bytes] = None):
|
149
|
+
"""Add node for obs tree."""
|
144
150
|
self.trace_id = trace_id
|
145
151
|
self.parent_span_id = parent_id
|
146
|
-
|
147
|
-
print("add parent")
|
148
|
-
print(f"name: {self.name}")
|
149
|
-
print(f"trace_id: {trace_id}")
|
150
|
-
print(f"span_id: {self.span_id}")
|
151
|
-
print(f"parent_span_id: {parent_id}")
|
@@ -1,9 +1,9 @@
|
|
1
|
-
divi/__init__.py,sha256
|
1
|
+
divi/__init__.py,sha256=lcpSVEjIcXy-e9CuJB8V1izwaoEK8YpH8FtkzH0IqJc,396
|
2
2
|
divi/utils.py,sha256=fXkjoyo_Lh8AZliKICOP460m0czUcNQjcEcceJbaOVA,1439
|
3
3
|
divi/config/config.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
4
4
|
divi/decorators/__init__.py,sha256=HkyWdC1ctTsVFucCWCkj57JB4NmwONus1d2S2dUbvs4,110
|
5
|
-
divi/decorators/obs_openai.py,sha256=
|
6
|
-
divi/decorators/observable.py,sha256=
|
5
|
+
divi/decorators/obs_openai.py,sha256=GI9c6gFArA6pTfa3EPednMtRqV2zIlofuTDdUYtS_x4,963
|
6
|
+
divi/decorators/observable.py,sha256=xKapTyHL50mUyIDhDSYIXR1yZIdHTuw6WtI4H0j1xDE,3464
|
7
7
|
divi/proto/common/v1/common.proto,sha256=Rx8wr0_tOtQ1NseTMnsav4ApD1MDALzQDBA2IvLRTU0,1775
|
8
8
|
divi/proto/common/v1/common_pb2.py,sha256=br61OHQVAi6SI3baFcb5xJv2Xd-AZ04A19xeSjLNMXo,2442
|
9
9
|
divi/proto/common/v1/common_pb2.pyi,sha256=LmTpFFLxHg2a_qPIdNXXwGEMkbiDcTJdarR9eC-6Fq8,2133
|
@@ -30,16 +30,16 @@ divi/services/core/core.py,sha256=PRwPtLgrgmCrejUfKf7HJNrAhGS0paFNZ7JwDToEUAk,12
|
|
30
30
|
divi/services/core/finish.py,sha256=dIGQpVXcJY4-tKe7A1_VV3yoSHNCDPfOlUltvzvk6VI,231
|
31
31
|
divi/services/core/init.py,sha256=e7-fgpOPglBXyEoPkgOAnpJk2ApdFbo7LPupxOb8N-w,1966
|
32
32
|
divi/services/datapark/__init__.py,sha256=GbV1mwHE07yutgOlCIYHykSEL5KJ-ApgLutGMzu2eUE,86
|
33
|
-
divi/services/datapark/datapark.py,sha256=
|
33
|
+
divi/services/datapark/datapark.py,sha256=d2pbrzVJtR3mNW1eQpbm-Wca-SvcfJqT7IuaQy7yHT0,2285
|
34
34
|
divi/services/datapark/init.py,sha256=C32f9t3eLsxcYNqEyheh6nW455G2oR0YhhdqBcbN3ec,92
|
35
35
|
divi/session/__init__.py,sha256=6lYemv21VQCIHx-xIdi7BxXcPNxVdvE60--8ArReUew,82
|
36
|
-
divi/session/session.py,sha256=
|
37
|
-
divi/session/setup.py,sha256=
|
36
|
+
divi/session/session.py,sha256=LlB2W2qGo0Vf-0L0CTQoXfzg_gCGpf0MTFsXQW7E6i4,817
|
37
|
+
divi/session/setup.py,sha256=NeCxCb-uYhkKnOEiw8dBQHz0DEL8j1oxzQY3cBAmHbo,1380
|
38
38
|
divi/session/teardown.py,sha256=YiBz_3yCiljMFEofZ60VmRL5sb8WA5GT7EYF8nFznZ4,133
|
39
39
|
divi/signals/__init__.py,sha256=K1PaTAMwyBDsK6jJUg4QWy0xVJ_5MA6dlWiUyJeiSQA,44
|
40
40
|
divi/signals/trace/__init__.py,sha256=K1PaTAMwyBDsK6jJUg4QWy0xVJ_5MA6dlWiUyJeiSQA,44
|
41
|
-
divi/signals/trace/trace.py,sha256=
|
42
|
-
divi-0.0.1.
|
43
|
-
divi-0.0.1.
|
44
|
-
divi-0.0.1.
|
45
|
-
divi-0.0.1.
|
41
|
+
divi/signals/trace/trace.py,sha256=OsfrZPHp241_NN8W79U4O69HsHQajez_d3rz6yJRN9s,4508
|
42
|
+
divi-0.0.1.dev23.dist-info/METADATA,sha256=KdspT1iEra11ixCEtl94Mz_fCziMVOOER08rDE4yCWU,497
|
43
|
+
divi-0.0.1.dev23.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
44
|
+
divi-0.0.1.dev23.dist-info/licenses/LICENSE,sha256=5OJuZ4wMMEV0DgF0tofhAlS_KLkaUsZwwwDS2U_GwQ0,1063
|
45
|
+
divi-0.0.1.dev23.dist-info/RECORD,,
|
File without changes
|
File without changes
|