scale-gp-beta 0.1.0a22__py3-none-any.whl → 0.1.0a24__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.
- scale_gp_beta/_version.py +1 -1
- scale_gp_beta/lib/tracing/span.py +154 -60
- scale_gp_beta/lib/tracing/trace.py +81 -41
- scale_gp_beta/lib/tracing/trace_queue_manager.py +7 -3
- scale_gp_beta/lib/tracing/tracing.py +10 -4
- {scale_gp_beta-0.1.0a22.dist-info → scale_gp_beta-0.1.0a24.dist-info}/METADATA +3 -3
- {scale_gp_beta-0.1.0a22.dist-info → scale_gp_beta-0.1.0a24.dist-info}/RECORD +9 -9
- {scale_gp_beta-0.1.0a22.dist-info → scale_gp_beta-0.1.0a24.dist-info}/WHEEL +0 -0
- {scale_gp_beta-0.1.0a22.dist-info → scale_gp_beta-0.1.0a24.dist-info}/licenses/LICENSE +0 -0
scale_gp_beta/_version.py
CHANGED
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
|
|
3
3
|
import logging
|
|
4
|
+
from copy import deepcopy
|
|
4
5
|
from typing import TYPE_CHECKING, Type, Optional
|
|
6
|
+
from threading import RLock
|
|
5
7
|
from typing_extensions import override
|
|
6
8
|
|
|
7
9
|
from scale_gp_beta.types.span_upsert_batch_params import Item as SpanCreateRequest
|
|
@@ -59,21 +61,22 @@ class BaseSpan:
|
|
|
59
61
|
metadata: Optional[SpanMetadataParam] = None,
|
|
60
62
|
span_type: SpanTypeLiterals = "STANDALONE"
|
|
61
63
|
):
|
|
62
|
-
self.
|
|
63
|
-
self.
|
|
64
|
-
self.
|
|
65
|
-
self.
|
|
66
|
-
self.
|
|
67
|
-
self.
|
|
68
|
-
self.
|
|
69
|
-
self.
|
|
70
|
-
self.
|
|
71
|
-
self.
|
|
72
|
-
self.
|
|
73
|
-
self.
|
|
64
|
+
self._name = name
|
|
65
|
+
self._trace_id: str = trace_id or "no_trace_id"
|
|
66
|
+
self._group_id = group_id
|
|
67
|
+
self._span_id: str = span_id or generate_span_id()
|
|
68
|
+
self._parent_span_id = parent_span_id
|
|
69
|
+
self._start_time: Optional[str] = None
|
|
70
|
+
self._end_time: Optional[str] = None
|
|
71
|
+
self._input: SpanInputParam = input or {}
|
|
72
|
+
self._output: SpanOutputParam = output or {}
|
|
73
|
+
self._metadata: SpanMetadataParam = metadata or {}
|
|
74
|
+
self._span_type: SpanTypeLiterals = span_type
|
|
75
|
+
self._status: SpanStatusLiterals = "SUCCESS"
|
|
74
76
|
self._queue_manager = queue_manager
|
|
75
77
|
|
|
76
78
|
self._contextvar_token: Optional[contextvars.Token[Optional[BaseSpan]]] = None
|
|
79
|
+
self._lock = RLock()
|
|
77
80
|
|
|
78
81
|
def start(self) -> None:
|
|
79
82
|
pass
|
|
@@ -84,6 +87,96 @@ class BaseSpan:
|
|
|
84
87
|
def flush(self, blocking: bool = True) -> None:
|
|
85
88
|
pass
|
|
86
89
|
|
|
90
|
+
@property
|
|
91
|
+
def name(self) -> str:
|
|
92
|
+
return self._name
|
|
93
|
+
|
|
94
|
+
@property
|
|
95
|
+
def trace_id(self) -> str:
|
|
96
|
+
return self._trace_id
|
|
97
|
+
|
|
98
|
+
@property
|
|
99
|
+
def group_id(self) -> Optional[str]:
|
|
100
|
+
return self._group_id
|
|
101
|
+
|
|
102
|
+
@property
|
|
103
|
+
def span_id(self) -> str:
|
|
104
|
+
return self._span_id
|
|
105
|
+
|
|
106
|
+
@property
|
|
107
|
+
def parent_span_id(self) -> Optional[str]:
|
|
108
|
+
return self._parent_span_id
|
|
109
|
+
|
|
110
|
+
@property
|
|
111
|
+
def status(self) -> SpanStatusLiterals:
|
|
112
|
+
return self._status
|
|
113
|
+
|
|
114
|
+
@property
|
|
115
|
+
def span_type(self) -> SpanTypeLiterals:
|
|
116
|
+
return self._span_type
|
|
117
|
+
|
|
118
|
+
# with setters
|
|
119
|
+
@property
|
|
120
|
+
def start_time(self) -> Optional[str]:
|
|
121
|
+
return self._start_time
|
|
122
|
+
|
|
123
|
+
@start_time.setter
|
|
124
|
+
def start_time(self, value: Optional[str]) -> None:
|
|
125
|
+
with self._lock:
|
|
126
|
+
self._start_time = value
|
|
127
|
+
|
|
128
|
+
@property
|
|
129
|
+
def end_time(self) -> Optional[str]:
|
|
130
|
+
return self._end_time
|
|
131
|
+
|
|
132
|
+
@end_time.setter
|
|
133
|
+
def end_time(self, value: Optional[str]) -> None:
|
|
134
|
+
with self._lock:
|
|
135
|
+
self._end_time = value
|
|
136
|
+
|
|
137
|
+
@property
|
|
138
|
+
def metadata(self) -> SpanMetadataParam:
|
|
139
|
+
return self._metadata
|
|
140
|
+
|
|
141
|
+
@metadata.setter
|
|
142
|
+
def metadata(self, value: SpanMetadataParam) -> None:
|
|
143
|
+
# this does not protect against span.metadata["foo"] = "bar" which uses the getter, ditto input and output
|
|
144
|
+
with self._lock:
|
|
145
|
+
self._metadata = value
|
|
146
|
+
|
|
147
|
+
@property
|
|
148
|
+
def input(self) -> SpanInputParam:
|
|
149
|
+
return self._input
|
|
150
|
+
|
|
151
|
+
@input.setter
|
|
152
|
+
def input(self, value: SpanInputParam) -> None:
|
|
153
|
+
with self._lock:
|
|
154
|
+
self._input = value
|
|
155
|
+
|
|
156
|
+
@property
|
|
157
|
+
def output(self) -> SpanOutputParam:
|
|
158
|
+
return self._output
|
|
159
|
+
|
|
160
|
+
@output.setter
|
|
161
|
+
def output(self, value: SpanOutputParam) -> None:
|
|
162
|
+
with self._lock:
|
|
163
|
+
self._output = value
|
|
164
|
+
|
|
165
|
+
def set_error(
|
|
166
|
+
self,
|
|
167
|
+
error_type: Optional[str] = None,
|
|
168
|
+
error_message: Optional[str] = None,
|
|
169
|
+
exception: Optional[BaseException] = None,
|
|
170
|
+
) -> None:
|
|
171
|
+
# Naively record details in metadata for now, note that error capture only supported in context manager
|
|
172
|
+
with self._lock:
|
|
173
|
+
exception_type = type(exception).__name__ if exception else None
|
|
174
|
+
exception_message = str(exception) if exception else None
|
|
175
|
+
self._status = "ERROR"
|
|
176
|
+
self.metadata["error"] = True
|
|
177
|
+
self.metadata["error_type"] = error_type or exception_type
|
|
178
|
+
self.metadata["error_message"] = error_message or exception_message
|
|
179
|
+
|
|
87
180
|
def __enter__(self) -> BaseSpan:
|
|
88
181
|
self.start()
|
|
89
182
|
return self
|
|
@@ -94,42 +187,41 @@ class BaseSpan:
|
|
|
94
187
|
exc_val: Optional[BaseException],
|
|
95
188
|
exc_tb: Optional[TracebackType]
|
|
96
189
|
) -> None:
|
|
97
|
-
# Naively record details in metadata for now, note that error capture only supported in context manager
|
|
98
190
|
# TODO: support error observations when using direct span.start() and span.end()
|
|
99
191
|
if exc_type is not None:
|
|
100
|
-
self.
|
|
101
|
-
self.metadata["error.type"] = exc_type.__name__
|
|
102
|
-
self.metadata["error.message"] = str(exc_val)
|
|
103
|
-
self.status = "ERROR"
|
|
192
|
+
self.set_error(exception=exc_val)
|
|
104
193
|
self.end()
|
|
105
194
|
|
|
106
195
|
def to_request_params(self) -> SpanCreateRequest:
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
196
|
+
with self._lock:
|
|
197
|
+
if self.start_time is None:
|
|
198
|
+
raise ParamsCreationError("No start time specified")
|
|
199
|
+
|
|
200
|
+
request_data = SpanCreateRequest(
|
|
201
|
+
name=self.name,
|
|
202
|
+
id=self.span_id,
|
|
203
|
+
trace_id=self.trace_id,
|
|
204
|
+
start_timestamp=self.start_time,
|
|
205
|
+
input=self.input,
|
|
206
|
+
output=self.output,
|
|
207
|
+
metadata=self.metadata,
|
|
208
|
+
status=self.status,
|
|
209
|
+
type=self.span_type
|
|
210
|
+
)
|
|
121
211
|
|
|
122
|
-
|
|
123
|
-
|
|
212
|
+
if self.end_time is not None:
|
|
213
|
+
request_data["end_timestamp"] = self.end_time
|
|
124
214
|
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
215
|
+
# parent_span_id is optional (root spans)
|
|
216
|
+
if self.parent_span_id is not None:
|
|
217
|
+
request_data["parent_id"] = self.parent_span_id
|
|
128
218
|
|
|
129
|
-
|
|
130
|
-
|
|
219
|
+
if self.group_id is not None:
|
|
220
|
+
request_data["group_id"] = self.group_id
|
|
131
221
|
|
|
132
|
-
|
|
222
|
+
# ensure no future changes to metadata, input or output changes request_data, full isolation
|
|
223
|
+
request_data = deepcopy(request_data)
|
|
224
|
+
return request_data
|
|
133
225
|
|
|
134
226
|
@override
|
|
135
227
|
def __repr__(self) -> str:
|
|
@@ -203,7 +295,7 @@ class Span(BaseSpan):
|
|
|
203
295
|
):
|
|
204
296
|
super().__init__(name, trace_id, queue_manager, span_id, parent_span_id, group_id, input, output, metadata, span_type)
|
|
205
297
|
self._queue_manager: TraceQueueManager = queue_manager
|
|
206
|
-
self.
|
|
298
|
+
self._trace_id: str = trace_id
|
|
207
299
|
|
|
208
300
|
@override
|
|
209
301
|
def flush(self, blocking: bool = True) -> None:
|
|
@@ -225,13 +317,14 @@ class Span(BaseSpan):
|
|
|
225
317
|
Sets the `start_time`, reports the span start to the `TraceQueueManager`
|
|
226
318
|
, and registers this span as the current span.
|
|
227
319
|
"""
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
320
|
+
with self._lock:
|
|
321
|
+
if self.start_time is not None:
|
|
322
|
+
log.warning(f"Span {self.name}: {self.span_id} has already started at {self.start_time}")
|
|
323
|
+
return
|
|
231
324
|
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
325
|
+
self.start_time = iso_timestamp()
|
|
326
|
+
self._queue_manager.report_span_start(self)
|
|
327
|
+
self._contextvar_token = Scope.set_current_span(self)
|
|
235
328
|
|
|
236
329
|
@override
|
|
237
330
|
def end(self) -> None:
|
|
@@ -241,19 +334,20 @@ class Span(BaseSpan):
|
|
|
241
334
|
`TraceQueueManager` for queuing and export, and resets this span from the
|
|
242
335
|
`Scope`.
|
|
243
336
|
"""
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
(
|
|
250
|
-
|
|
251
|
-
|
|
337
|
+
with self._lock:
|
|
338
|
+
if self.end_time is not None:
|
|
339
|
+
log.warning(f"Span {self.name}: {self.span_id} has already ended at {self.end_time}")
|
|
340
|
+
return
|
|
341
|
+
if self._contextvar_token is None:
|
|
342
|
+
log.warning(
|
|
343
|
+
(
|
|
344
|
+
f"Span {self.name}: {self.span_id} attempting to end without a valid context token. "
|
|
345
|
+
"Was start() called and completed successfully?"
|
|
346
|
+
)
|
|
252
347
|
)
|
|
253
|
-
|
|
254
|
-
return
|
|
348
|
+
return
|
|
255
349
|
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
350
|
+
self.end_time = iso_timestamp()
|
|
351
|
+
self._queue_manager.report_span_end(self)
|
|
352
|
+
Scope.reset_current_span(self._contextvar_token)
|
|
353
|
+
self._contextvar_token = None
|
|
@@ -4,23 +4,30 @@ from types import TracebackType
|
|
|
4
4
|
from typing import Type, Optional
|
|
5
5
|
from typing_extensions import override
|
|
6
6
|
|
|
7
|
-
from .span import Span, NoOpSpan
|
|
7
|
+
from .span import Span, BaseSpan, NoOpSpan
|
|
8
8
|
from .util import generate_trace_id
|
|
9
9
|
from .scope import Scope
|
|
10
|
-
from .types import SpanInputParam, SpanOutputParam, SpanTypeLiterals, SpanMetadataParam
|
|
10
|
+
from .types import SpanInputParam, SpanOutputParam, SpanTypeLiterals, SpanMetadataParam, SpanStatusLiterals
|
|
11
11
|
from .trace_queue_manager import TraceQueueManager
|
|
12
12
|
|
|
13
13
|
log: logging.Logger = logging.getLogger(__name__)
|
|
14
14
|
|
|
15
15
|
|
|
16
16
|
class BaseTrace:
|
|
17
|
-
def __init__(
|
|
18
|
-
|
|
17
|
+
def __init__(
|
|
18
|
+
self,
|
|
19
|
+
queue_manager: Optional[TraceQueueManager],
|
|
20
|
+
root_span: BaseSpan,
|
|
21
|
+
trace_id: str
|
|
22
|
+
) -> None:
|
|
23
|
+
self._trace_id = trace_id
|
|
19
24
|
self.queue_manager = queue_manager
|
|
20
25
|
|
|
21
26
|
self._in_progress = False
|
|
22
27
|
self._contextvar_token: Optional[contextvars.Token[Optional[BaseTrace]]] = None
|
|
23
28
|
|
|
29
|
+
self.root_span = root_span
|
|
30
|
+
|
|
24
31
|
def start(self) -> None:
|
|
25
32
|
pass
|
|
26
33
|
|
|
@@ -30,8 +37,62 @@ class BaseTrace:
|
|
|
30
37
|
def flush(self, blocking: bool = True) -> None:
|
|
31
38
|
pass
|
|
32
39
|
|
|
40
|
+
@property
|
|
41
|
+
def metadata(self) -> SpanMetadataParam:
|
|
42
|
+
return self.root_span.metadata
|
|
43
|
+
|
|
44
|
+
@metadata.setter
|
|
45
|
+
def metadata(self, value: SpanMetadataParam) -> None:
|
|
46
|
+
self.root_span.metadata = value
|
|
47
|
+
|
|
48
|
+
@property
|
|
49
|
+
def input(self) -> SpanInputParam:
|
|
50
|
+
return self.root_span.input
|
|
51
|
+
|
|
52
|
+
@input.setter
|
|
53
|
+
def input(self, value: SpanInputParam) -> None:
|
|
54
|
+
self.root_span.input = value
|
|
55
|
+
|
|
56
|
+
@property
|
|
57
|
+
def output(self) -> SpanOutputParam:
|
|
58
|
+
return self.root_span.output
|
|
59
|
+
|
|
60
|
+
@output.setter
|
|
61
|
+
def output(self, value: SpanOutputParam) -> None:
|
|
62
|
+
self.root_span.output = value
|
|
63
|
+
|
|
64
|
+
# no setters
|
|
65
|
+
@property
|
|
66
|
+
def name(self) -> Optional[str]:
|
|
67
|
+
return self.root_span.name
|
|
68
|
+
|
|
69
|
+
@property
|
|
70
|
+
def span_id(self) -> Optional[str]:
|
|
71
|
+
return self.root_span.span_id
|
|
72
|
+
|
|
73
|
+
@property
|
|
74
|
+
def trace_id(self) -> Optional[str]:
|
|
75
|
+
return self._trace_id
|
|
76
|
+
|
|
77
|
+
@property
|
|
33
78
|
def group_id(self) -> Optional[str]:
|
|
34
|
-
return
|
|
79
|
+
return self.root_span.group_id
|
|
80
|
+
|
|
81
|
+
@property
|
|
82
|
+
def span_type(self) -> SpanTypeLiterals:
|
|
83
|
+
return self.root_span.span_type
|
|
84
|
+
|
|
85
|
+
@property
|
|
86
|
+
def status(self) -> SpanStatusLiterals:
|
|
87
|
+
return self.root_span.status
|
|
88
|
+
|
|
89
|
+
def set_error(
|
|
90
|
+
self,
|
|
91
|
+
error_type: Optional[str] = None,
|
|
92
|
+
error_message: Optional[str] = None,
|
|
93
|
+
exception: Optional[BaseException] = None,
|
|
94
|
+
) -> None:
|
|
95
|
+
self.root_span.set_error(error_type=error_type, error_message=error_message, exception=exception)
|
|
35
96
|
|
|
36
97
|
def __enter__(self) -> "BaseTrace":
|
|
37
98
|
self.start()
|
|
@@ -47,7 +108,12 @@ class BaseTrace:
|
|
|
47
108
|
|
|
48
109
|
@override
|
|
49
110
|
def __repr__(self) -> str:
|
|
50
|
-
return
|
|
111
|
+
return (
|
|
112
|
+
f"{self.__class__.__name__}("
|
|
113
|
+
f"trace_id='{self.trace_id}', "
|
|
114
|
+
f"root_span='{repr(self.root_span)}', "
|
|
115
|
+
")"
|
|
116
|
+
)
|
|
51
117
|
|
|
52
118
|
@override
|
|
53
119
|
def __str__(self) -> str:
|
|
@@ -67,12 +133,11 @@ class NoOpTrace(BaseTrace):
|
|
|
67
133
|
output: Optional[SpanOutputParam] = None,
|
|
68
134
|
metadata: Optional[SpanMetadataParam] = None,
|
|
69
135
|
):
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
self.root_span = NoOpSpan(
|
|
136
|
+
trace_id = trace_id or generate_trace_id()
|
|
137
|
+
root_span = NoOpSpan(
|
|
73
138
|
name=name,
|
|
74
139
|
span_id=span_id,
|
|
75
|
-
trace_id=
|
|
140
|
+
trace_id=trace_id,
|
|
76
141
|
group_id=group_id,
|
|
77
142
|
queue_manager=queue_manager,
|
|
78
143
|
metadata=metadata,
|
|
@@ -80,15 +145,7 @@ class NoOpTrace(BaseTrace):
|
|
|
80
145
|
input=input,
|
|
81
146
|
output=output,
|
|
82
147
|
)
|
|
83
|
-
|
|
84
|
-
@override
|
|
85
|
-
def __repr__(self) -> str:
|
|
86
|
-
return (
|
|
87
|
-
f"{self.__class__.__name__}("
|
|
88
|
-
f"trace_id='{self.trace_id}', "
|
|
89
|
-
f"root_span='{repr(self.root_span)}', "
|
|
90
|
-
")"
|
|
91
|
-
)
|
|
148
|
+
super().__init__(queue_manager, root_span, trace_id)
|
|
92
149
|
|
|
93
150
|
@override
|
|
94
151
|
def start(self) -> None:
|
|
@@ -98,10 +155,6 @@ class NoOpTrace(BaseTrace):
|
|
|
98
155
|
def end(self) -> None:
|
|
99
156
|
self.root_span.end()
|
|
100
157
|
|
|
101
|
-
@override
|
|
102
|
-
def group_id(self) -> Optional[str]:
|
|
103
|
-
return self.root_span.group_id
|
|
104
|
-
|
|
105
158
|
|
|
106
159
|
class Trace(BaseTrace):
|
|
107
160
|
def __init__(
|
|
@@ -116,13 +169,11 @@ class Trace(BaseTrace):
|
|
|
116
169
|
output: Optional[SpanOutputParam] = None,
|
|
117
170
|
metadata: Optional[SpanMetadataParam] = None,
|
|
118
171
|
):
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
self.root_span = Span(
|
|
172
|
+
trace_id = trace_id or generate_trace_id()
|
|
173
|
+
root_span = Span(
|
|
123
174
|
name=name,
|
|
124
175
|
span_id=span_id,
|
|
125
|
-
trace_id=
|
|
176
|
+
trace_id=trace_id,
|
|
126
177
|
group_id=group_id,
|
|
127
178
|
queue_manager=queue_manager,
|
|
128
179
|
metadata=metadata,
|
|
@@ -130,6 +181,8 @@ class Trace(BaseTrace):
|
|
|
130
181
|
input=input,
|
|
131
182
|
output=output,
|
|
132
183
|
)
|
|
184
|
+
super().__init__(queue_manager, root_span, trace_id)
|
|
185
|
+
self.queue_manager: TraceQueueManager = queue_manager
|
|
133
186
|
|
|
134
187
|
@override
|
|
135
188
|
def start(self) -> None:
|
|
@@ -162,16 +215,3 @@ class Trace(BaseTrace):
|
|
|
162
215
|
@override
|
|
163
216
|
def flush(self, blocking: bool = True) -> None:
|
|
164
217
|
self.root_span.flush(blocking=blocking)
|
|
165
|
-
|
|
166
|
-
@override
|
|
167
|
-
def group_id(self) -> Optional[str]:
|
|
168
|
-
return self.root_span.group_id
|
|
169
|
-
|
|
170
|
-
@override
|
|
171
|
-
def __repr__(self) -> str:
|
|
172
|
-
return (
|
|
173
|
-
f"{self.__class__.__name__}("
|
|
174
|
-
f"trace_id='{self.trace_id}', "
|
|
175
|
-
f"root_span='{repr(self.root_span)}', "
|
|
176
|
-
")"
|
|
177
|
-
)
|
|
@@ -30,7 +30,7 @@ class TraceQueueManager:
|
|
|
30
30
|
"""Manage trace and spans queue
|
|
31
31
|
Store spans in-memory until the threshold has been reached then flush to server.
|
|
32
32
|
|
|
33
|
-
Optionally provide a client, if unprovided we will attempt to create a default client.
|
|
33
|
+
Optionally provide a client, if unprovided, we will attempt to create a default client.
|
|
34
34
|
"""
|
|
35
35
|
|
|
36
36
|
def __init__(
|
|
@@ -41,6 +41,7 @@ class TraceQueueManager:
|
|
|
41
41
|
trigger_queue_size: int = DEFAULT_TRIGGER_QUEUE_SIZE,
|
|
42
42
|
trigger_cadence: float = DEFAULT_TRIGGER_CADENCE,
|
|
43
43
|
retries: int = DEFAULT_RETRIES,
|
|
44
|
+
worker_enabled: Optional[bool] = None,
|
|
44
45
|
):
|
|
45
46
|
self._client = client
|
|
46
47
|
self._attempted_local_client_creation = False
|
|
@@ -54,7 +55,9 @@ class TraceQueueManager:
|
|
|
54
55
|
self._shutdown_event = threading.Event()
|
|
55
56
|
self._queue: queue.Queue[Span] = queue.Queue(maxsize=max_queue_size)
|
|
56
57
|
|
|
57
|
-
if not is_disabled()
|
|
58
|
+
self._worker_enabled = worker_enabled if worker_enabled is not None else not is_disabled()
|
|
59
|
+
|
|
60
|
+
if self._worker_enabled:
|
|
58
61
|
self._worker = threading.Thread(daemon=True, target=self._run)
|
|
59
62
|
self._worker.start()
|
|
60
63
|
|
|
@@ -66,7 +69,7 @@ class TraceQueueManager:
|
|
|
66
69
|
self._client = client
|
|
67
70
|
|
|
68
71
|
def shutdown(self, timeout: Optional[float] = None) -> None:
|
|
69
|
-
if
|
|
72
|
+
if not self._worker_enabled:
|
|
70
73
|
log.debug("No worker to shutdown")
|
|
71
74
|
return
|
|
72
75
|
log.info(f"Shutting down trace queue manager, joining worker thread with timeout {timeout}")
|
|
@@ -92,6 +95,7 @@ class TraceQueueManager:
|
|
|
92
95
|
|
|
93
96
|
def enqueue(self, span: "Span") -> None:
|
|
94
97
|
try:
|
|
98
|
+
# Should this be a deep copy of span instead? Currently is a reference
|
|
95
99
|
self._queue.put_nowait(span)
|
|
96
100
|
except queue.Full:
|
|
97
101
|
log.warning(f"Queue full, ignoring span {span.span_id}")
|
|
@@ -6,7 +6,7 @@ from .util import is_disabled
|
|
|
6
6
|
from .scope import Scope
|
|
7
7
|
from .trace import Trace, BaseTrace, NoOpTrace
|
|
8
8
|
from .types import SpanInputParam, SpanOutputParam, SpanTypeLiterals, SpanMetadataParam
|
|
9
|
-
from .trace_queue_manager import tracing_queue_manager
|
|
9
|
+
from .trace_queue_manager import TraceQueueManager, tracing_queue_manager
|
|
10
10
|
|
|
11
11
|
log: logging.Logger = logging.getLogger(__name__)
|
|
12
12
|
|
|
@@ -58,6 +58,7 @@ def create_trace(
|
|
|
58
58
|
span_id: Optional[str] = None,
|
|
59
59
|
trace_id: Optional[str] = None,
|
|
60
60
|
group_id: Optional[str] = None,
|
|
61
|
+
queue_manager: Optional[TraceQueueManager] = None,
|
|
61
62
|
) -> BaseTrace:
|
|
62
63
|
"""Creates a new trace and root span instance.
|
|
63
64
|
|
|
@@ -83,6 +84,8 @@ def create_trace(
|
|
|
83
84
|
If None, a unique trace ID will be generated.
|
|
84
85
|
Max length is 38 characters.
|
|
85
86
|
group_id (Optional[str]): An optional, id to group traces.
|
|
87
|
+
queue_manager (Optional[TraceQueueManager], optional): An optional `TraceQueueManager`.
|
|
88
|
+
Useful for when you need explicit control of flushing and client behavior.
|
|
86
89
|
|
|
87
90
|
Returns:
|
|
88
91
|
BaseTrace: A `Trace` instance if tracing is enabled, or a `NoOpTrace`
|
|
@@ -109,7 +112,7 @@ def create_trace(
|
|
|
109
112
|
if active_trace is not None:
|
|
110
113
|
log.warning(f"Trace with id {active_trace.trace_id} is already active. Creating a new trace anyways.")
|
|
111
114
|
|
|
112
|
-
queue_manager = tracing_queue_manager()
|
|
115
|
+
queue_manager = queue_manager or tracing_queue_manager()
|
|
113
116
|
trace = Trace(
|
|
114
117
|
name=name,
|
|
115
118
|
trace_id=trace_id,
|
|
@@ -136,6 +139,7 @@ def create_span(
|
|
|
136
139
|
parent_id: Optional[str] = None,
|
|
137
140
|
trace_id: Optional[str] = None,
|
|
138
141
|
group_id: Optional[str] = None,
|
|
142
|
+
queue_manager: Optional[TraceQueueManager] = None,
|
|
139
143
|
) -> BaseSpan:
|
|
140
144
|
"""Creates a new span instance.
|
|
141
145
|
|
|
@@ -171,6 +175,8 @@ def create_span(
|
|
|
171
175
|
trace_id (Optional[str], optional): A `Trace` id. Used for explicit control.
|
|
172
176
|
Default to trace id fetched from the active scope.
|
|
173
177
|
group_id (Optional[str]): An optional, id to group traces.
|
|
178
|
+
queue_manager (Optional[TraceQueueManager], optional): An optional `TraceQueueManager`.
|
|
179
|
+
Useful for when you need explicit control of flushing and client behavior.
|
|
174
180
|
|
|
175
181
|
Returns:
|
|
176
182
|
BaseSpan: A `Span` instance if tracing is enabled and a valid trace context
|
|
@@ -182,7 +188,7 @@ def create_span(
|
|
|
182
188
|
|
|
183
189
|
scoped_trace = current_trace()
|
|
184
190
|
scoped_trace_id = scoped_trace.trace_id if scoped_trace else None
|
|
185
|
-
scoped_group_id = scoped_trace.group_id
|
|
191
|
+
scoped_group_id = scoped_trace.group_id if scoped_trace else None
|
|
186
192
|
scoped_span = current_span()
|
|
187
193
|
scoped_span_id = scoped_span.span_id if scoped_span else None
|
|
188
194
|
|
|
@@ -213,7 +219,7 @@ def create_span(
|
|
|
213
219
|
log.debug(f"Attempting to create a span with no trace")
|
|
214
220
|
return noop_span
|
|
215
221
|
|
|
216
|
-
queue_manager = tracing_queue_manager()
|
|
222
|
+
queue_manager = queue_manager or tracing_queue_manager()
|
|
217
223
|
span = Span(
|
|
218
224
|
name=name,
|
|
219
225
|
span_id=span_id,
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.3
|
|
2
2
|
Name: scale-gp-beta
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.0a24
|
|
4
4
|
Summary: The official Python library for the Scale GP API
|
|
5
5
|
Project-URL: Homepage, https://github.com/scaleapi/sgp-python-beta
|
|
6
6
|
Project-URL: Repository, https://github.com/scaleapi/sgp-python-beta
|
|
@@ -31,7 +31,7 @@ Description-Content-Type: text/markdown
|
|
|
31
31
|
|
|
32
32
|
# Scale GP Python API library
|
|
33
33
|
|
|
34
|
-
[](https://pypi.org/project/scale-gp-beta/)
|
|
34
|
+
[>)](https://pypi.org/project/scale-gp-beta/)
|
|
35
35
|
|
|
36
36
|
The Scale GP Python library provides convenient access to the Scale GP REST API from any Python 3.8+
|
|
37
37
|
application. The library includes type definitions for all request params and response fields,
|
|
@@ -578,7 +578,7 @@ client.with_options(max_retries=5).chat.completions.create(
|
|
|
578
578
|
### Timeouts
|
|
579
579
|
|
|
580
580
|
By default requests time out after 1 minute. You can configure this with a `timeout` option,
|
|
581
|
-
which accepts a float or an [`httpx.Timeout`](https://www.python-httpx.org/advanced/#fine-tuning-the-configuration) object:
|
|
581
|
+
which accepts a float or an [`httpx.Timeout`](https://www.python-httpx.org/advanced/timeouts/#fine-tuning-the-configuration) object:
|
|
582
582
|
|
|
583
583
|
```python
|
|
584
584
|
from scale_gp_beta import SGPClient
|
|
@@ -11,7 +11,7 @@ scale_gp_beta/_resource.py,sha256=siZly_U6D0AOVLAzaOsqUdEFFzVMbWRj-ml30nvRp7E,11
|
|
|
11
11
|
scale_gp_beta/_response.py,sha256=GemuybPk0uemovTlGHyHkj-ScYTTDJA0jqH5FQqIPwQ,28852
|
|
12
12
|
scale_gp_beta/_streaming.py,sha256=fcCSGXslmi2SmmkM05g2SACXHk2Mj7k1X5uMBu6U5s8,10112
|
|
13
13
|
scale_gp_beta/_types.py,sha256=0wSs40TefKMPBj2wQKenEeZ0lzedoHClNJeqrpAgkII,6204
|
|
14
|
-
scale_gp_beta/_version.py,sha256=
|
|
14
|
+
scale_gp_beta/_version.py,sha256=7E-g0q6eQvQbS2pu4ASnulYRwTSdV6WaybxYdb6Zhpg,174
|
|
15
15
|
scale_gp_beta/pagination.py,sha256=t-U86PYxl20VRsz8VXOMJJDe7HxkX7ISFMvRNbBNy9s,4054
|
|
16
16
|
scale_gp_beta/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
17
17
|
scale_gp_beta/_utils/__init__.py,sha256=PNZ_QJuzZEgyYXqkO1HVhGkj5IU9bglVUcw7H-Knjzw,2062
|
|
@@ -28,11 +28,11 @@ scale_gp_beta/lib/.keep,sha256=wuNrz-5SXo3jJaJOJgz4vFHM41YH_g20F5cRQo0vLes,224
|
|
|
28
28
|
scale_gp_beta/lib/tracing/__init__.py,sha256=UgyExbqAA2ljDEF4X4YFhtbBZuoQJ2IF4hkGs_xQEc0,226
|
|
29
29
|
scale_gp_beta/lib/tracing/exceptions.py,sha256=vL2_GAfWEy8EfLhrBkDClLYTasOLnL-5zUpdCQnSzcs,107
|
|
30
30
|
scale_gp_beta/lib/tracing/scope.py,sha256=kHrd0his8L2K_KXn2E6J9d565PliEdFoKRQ1d5ALTyk,3901
|
|
31
|
-
scale_gp_beta/lib/tracing/span.py,sha256=
|
|
32
|
-
scale_gp_beta/lib/tracing/trace.py,sha256=
|
|
31
|
+
scale_gp_beta/lib/tracing/span.py,sha256=jmi1IYkPSAw_26bid7fCpiAWmyjW8XjaoonX70ydXPc,12448
|
|
32
|
+
scale_gp_beta/lib/tracing/trace.py,sha256=sdLUnvByLaMbV2TgI-MdKKs7If1-6GKz5j9A6scnDoI,6205
|
|
33
33
|
scale_gp_beta/lib/tracing/trace_exporter.py,sha256=bE6hS-Qu9KknEUTdsfIQMQwauah125mEavTDqEenBRA,3779
|
|
34
|
-
scale_gp_beta/lib/tracing/trace_queue_manager.py,sha256=
|
|
35
|
-
scale_gp_beta/lib/tracing/tracing.py,sha256=
|
|
34
|
+
scale_gp_beta/lib/tracing/trace_queue_manager.py,sha256=RnEDOKi7c1xlKXUsofShzZ8WrHldbhc0wyveMNgX8E4,6206
|
|
35
|
+
scale_gp_beta/lib/tracing/tracing.py,sha256=_j30MMy-w5Y33t2lAYSFVpMY_Ia2PFcEFaUEG5UN2OI,9368
|
|
36
36
|
scale_gp_beta/lib/tracing/types.py,sha256=fnU7XGiyfF3UEIx-iqyHRjNHlOV7s75tP0b5efvt2sk,1156
|
|
37
37
|
scale_gp_beta/lib/tracing/util.py,sha256=8Oq4wLXRNOzh3CC1zRaBEr0h_WdXLrk536BUNKRddVE,1527
|
|
38
38
|
scale_gp_beta/resources/__init__.py,sha256=Fyo05_2_pc5orfyTSIpxa3btmBTd45VasgibwSqbbKo,4942
|
|
@@ -117,7 +117,7 @@ scale_gp_beta/types/chat/completion_models_params.py,sha256=ETxafJIUx4tTvkiR-ZCr
|
|
|
117
117
|
scale_gp_beta/types/chat/completion_models_response.py,sha256=Ctgj6o-QWPSdjBKzG9J4Id0-DjXu4UGGw1NR6-840Ec,403
|
|
118
118
|
scale_gp_beta/types/chat/model_definition.py,sha256=NNgopTm900GD0Zs2YHkcvoW67uKaWUKVyPbhKBHvKdQ,817
|
|
119
119
|
scale_gp_beta/types/files/__init__.py,sha256=OKfJYcKb4NObdiRObqJV_dOyDQ8feXekDUge2o_4pXQ,122
|
|
120
|
-
scale_gp_beta-0.1.
|
|
121
|
-
scale_gp_beta-0.1.
|
|
122
|
-
scale_gp_beta-0.1.
|
|
123
|
-
scale_gp_beta-0.1.
|
|
120
|
+
scale_gp_beta-0.1.0a24.dist-info/METADATA,sha256=orXAxIkeUTgNuTWIfGt97BdKdhLi4NBJmg55IZ4cwEA,27611
|
|
121
|
+
scale_gp_beta-0.1.0a24.dist-info/WHEEL,sha256=C2FUgwZgiLbznR-k0b_5k3Ai_1aASOXDss3lzCUsUug,87
|
|
122
|
+
scale_gp_beta-0.1.0a24.dist-info/licenses/LICENSE,sha256=x49Bj8r_ZpqfzThbmfHyZ_bE88XvHdIMI_ANyLHFFRE,11338
|
|
123
|
+
scale_gp_beta-0.1.0a24.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|