scale-gp-beta 0.1.0a18__py3-none-any.whl → 0.1.0a20__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 +56 -20
- scale_gp_beta/lib/tracing/trace.py +46 -9
- scale_gp_beta/lib/tracing/trace_exporter.py +25 -5
- scale_gp_beta/lib/tracing/trace_queue_manager.py +12 -8
- scale_gp_beta/lib/tracing/tracing.py +88 -48
- scale_gp_beta/lib/tracing/types.py +7 -2
- {scale_gp_beta-0.1.0a18.dist-info → scale_gp_beta-0.1.0a20.dist-info}/METADATA +1 -1
- {scale_gp_beta-0.1.0a18.dist-info → scale_gp_beta-0.1.0a20.dist-info}/RECORD +11 -11
- {scale_gp_beta-0.1.0a18.dist-info → scale_gp_beta-0.1.0a20.dist-info}/WHEEL +0 -0
- {scale_gp_beta-0.1.0a18.dist-info → scale_gp_beta-0.1.0a20.dist-info}/licenses/LICENSE +0 -0
scale_gp_beta/_version.py
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
|
|
3
3
|
import logging
|
|
4
|
-
from typing import TYPE_CHECKING,
|
|
4
|
+
from typing import TYPE_CHECKING, Type, Optional
|
|
5
5
|
from typing_extensions import override
|
|
6
6
|
|
|
7
7
|
from scale_gp_beta.types.span_upsert_batch_params import Item as SpanCreateRequest
|
|
8
8
|
|
|
9
9
|
from .util import iso_timestamp, generate_span_id
|
|
10
10
|
from .scope import Scope
|
|
11
|
-
from .types import SpanTypeLiterals, SpanStatusLiterals
|
|
11
|
+
from .types import SpanInputParam, SpanOutputParam, SpanTypeLiterals, SpanMetadataParam, SpanStatusLiterals
|
|
12
12
|
from .exceptions import ParamsCreationError
|
|
13
13
|
|
|
14
14
|
if TYPE_CHECKING:
|
|
@@ -53,9 +53,9 @@ class BaseSpan:
|
|
|
53
53
|
queue_manager: Optional[TraceQueueManager] = None,
|
|
54
54
|
span_id: Optional[str] = None,
|
|
55
55
|
parent_span_id: Optional[str] = None,
|
|
56
|
-
input: Optional[
|
|
57
|
-
output: Optional[
|
|
58
|
-
metadata: Optional[
|
|
56
|
+
input: Optional[SpanInputParam] = None,
|
|
57
|
+
output: Optional[SpanOutputParam] = None,
|
|
58
|
+
metadata: Optional[SpanMetadataParam] = None,
|
|
59
59
|
span_type: SpanTypeLiterals = "STANDALONE"
|
|
60
60
|
):
|
|
61
61
|
self.name = name
|
|
@@ -64,9 +64,9 @@ class BaseSpan:
|
|
|
64
64
|
self.parent_span_id = parent_span_id
|
|
65
65
|
self.start_time: Optional[str] = None
|
|
66
66
|
self.end_time: Optional[str] = None
|
|
67
|
-
self.input = input
|
|
68
|
-
self.output = output
|
|
69
|
-
self.metadata = metadata
|
|
67
|
+
self.input: SpanInputParam = input or {}
|
|
68
|
+
self.output: SpanOutputParam = output or {}
|
|
69
|
+
self.metadata: SpanMetadataParam = metadata or {}
|
|
70
70
|
self.span_type: SpanTypeLiterals = span_type
|
|
71
71
|
self.status: SpanStatusLiterals = "SUCCESS"
|
|
72
72
|
self._queue_manager = queue_manager
|
|
@@ -79,6 +79,9 @@ class BaseSpan:
|
|
|
79
79
|
def end(self) -> None:
|
|
80
80
|
pass
|
|
81
81
|
|
|
82
|
+
def flush(self, blocking: bool = True) -> None:
|
|
83
|
+
pass
|
|
84
|
+
|
|
82
85
|
def __enter__(self) -> BaseSpan:
|
|
83
86
|
self.start()
|
|
84
87
|
return self
|
|
@@ -92,8 +95,6 @@ class BaseSpan:
|
|
|
92
95
|
# Naively record details in metadata for now, note that error capture only supported in context manager
|
|
93
96
|
# TODO: support error observations when using direct span.start() and span.end()
|
|
94
97
|
if exc_type is not None:
|
|
95
|
-
if self.metadata is None:
|
|
96
|
-
self.metadata = {}
|
|
97
98
|
self.metadata["error"] = True
|
|
98
99
|
self.metadata["error.type"] = exc_type.__name__
|
|
99
100
|
self.metadata["error.message"] = str(exc_val)
|
|
@@ -103,29 +104,50 @@ class BaseSpan:
|
|
|
103
104
|
def to_request_params(self) -> SpanCreateRequest:
|
|
104
105
|
if self.start_time is None:
|
|
105
106
|
raise ParamsCreationError("No start time specified")
|
|
106
|
-
if self.end_time is None:
|
|
107
|
-
# Can relax this check if we decide to allow span POSTs on creation.
|
|
108
|
-
raise ParamsCreationError("No end time specified")
|
|
109
107
|
|
|
110
108
|
request_data = SpanCreateRequest(
|
|
111
109
|
name=self.name,
|
|
112
110
|
id=self.span_id,
|
|
113
111
|
trace_id=self.trace_id,
|
|
114
112
|
start_timestamp=self.start_time,
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
metadata=self.metadata or {},
|
|
113
|
+
input=self.input,
|
|
114
|
+
output=self.output,
|
|
115
|
+
metadata=self.metadata,
|
|
119
116
|
status=self.status,
|
|
120
117
|
type=self.span_type
|
|
121
118
|
)
|
|
122
119
|
|
|
120
|
+
if self.end_time is not None:
|
|
121
|
+
request_data["end_timestamp"] = self.end_time
|
|
122
|
+
|
|
123
123
|
# parent_span_id is optional (root spans)
|
|
124
124
|
if self.parent_span_id is not None:
|
|
125
125
|
request_data["parent_id"] = self.parent_span_id
|
|
126
126
|
|
|
127
127
|
return request_data
|
|
128
128
|
|
|
129
|
+
@override
|
|
130
|
+
def __repr__(self) -> str:
|
|
131
|
+
return (
|
|
132
|
+
f"{self.__class__.__name__}("
|
|
133
|
+
f"name='{self.name}', "
|
|
134
|
+
f"span_id='{self.span_id}', "
|
|
135
|
+
f"trace_id='{self.trace_id}', "
|
|
136
|
+
f"parent_span_id='{self.parent_span_id}', "
|
|
137
|
+
f"start_time='{self.start_time}', "
|
|
138
|
+
f"end_time='{self.end_time}', "
|
|
139
|
+
f"input='{self.input}', "
|
|
140
|
+
f"output='{self.output}', "
|
|
141
|
+
f"metadata='{self.metadata}', "
|
|
142
|
+
f"span_type='{self.span_type}', "
|
|
143
|
+
f"status='{self.status}'"
|
|
144
|
+
")"
|
|
145
|
+
)
|
|
146
|
+
|
|
147
|
+
@override
|
|
148
|
+
def __str__(self) -> str:
|
|
149
|
+
return self.__repr__()
|
|
150
|
+
|
|
129
151
|
|
|
130
152
|
class NoOpSpan(BaseSpan):
|
|
131
153
|
@override
|
|
@@ -167,15 +189,29 @@ class Span(BaseSpan):
|
|
|
167
189
|
queue_manager: TraceQueueManager,
|
|
168
190
|
span_id: Optional[str] = None,
|
|
169
191
|
parent_span_id: Optional[str] = None,
|
|
170
|
-
input: Optional[
|
|
171
|
-
output: Optional[
|
|
172
|
-
metadata: Optional[
|
|
192
|
+
input: Optional[SpanInputParam] = None,
|
|
193
|
+
output: Optional[SpanOutputParam] = None,
|
|
194
|
+
metadata: Optional[SpanMetadataParam] = None,
|
|
173
195
|
span_type: SpanTypeLiterals = "STANDALONE",
|
|
174
196
|
):
|
|
175
197
|
super().__init__(name, trace_id, queue_manager, span_id, parent_span_id, input, output, metadata, span_type)
|
|
176
198
|
self._queue_manager: TraceQueueManager = queue_manager
|
|
177
199
|
self.trace_id: str = trace_id
|
|
178
200
|
|
|
201
|
+
@override
|
|
202
|
+
def flush(self, blocking: bool = True) -> None:
|
|
203
|
+
"""Export span. Defaults to in-thread and will block until the request is complete.
|
|
204
|
+
|
|
205
|
+
With `blocking=False`, this method will enqueue the request for the background worker.
|
|
206
|
+
The background worker batches and sends asynchronously.
|
|
207
|
+
:param blocking:
|
|
208
|
+
"""
|
|
209
|
+
# TODO: implement flush() for trace
|
|
210
|
+
if blocking:
|
|
211
|
+
self._queue_manager.export_now(self)
|
|
212
|
+
else:
|
|
213
|
+
self._queue_manager.enqueue(self)
|
|
214
|
+
|
|
179
215
|
@override
|
|
180
216
|
def start(self) -> None:
|
|
181
217
|
"""Starts the operational Span.
|
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
import logging
|
|
2
2
|
import contextvars
|
|
3
3
|
from types import TracebackType
|
|
4
|
-
from typing import
|
|
4
|
+
from typing import Type, Optional
|
|
5
5
|
from typing_extensions import override
|
|
6
6
|
|
|
7
7
|
from .span import Span, NoOpSpan
|
|
8
8
|
from .util import generate_trace_id
|
|
9
9
|
from .scope import Scope
|
|
10
|
+
from .types import SpanInputParam, SpanOutputParam, SpanTypeLiterals, SpanMetadataParam
|
|
10
11
|
from .trace_queue_manager import TraceQueueManager
|
|
11
12
|
|
|
12
13
|
log: logging.Logger = logging.getLogger(__name__)
|
|
@@ -38,6 +39,14 @@ class BaseTrace:
|
|
|
38
39
|
) -> None:
|
|
39
40
|
self.end()
|
|
40
41
|
|
|
42
|
+
@override
|
|
43
|
+
def __repr__(self) -> str:
|
|
44
|
+
return f"{self.__class__.__name__}(trace_id='{self.trace_id})"
|
|
45
|
+
|
|
46
|
+
@override
|
|
47
|
+
def __str__(self) -> str:
|
|
48
|
+
return self.__repr__()
|
|
49
|
+
|
|
41
50
|
|
|
42
51
|
class NoOpTrace(BaseTrace):
|
|
43
52
|
def __init__(
|
|
@@ -45,18 +54,32 @@ class NoOpTrace(BaseTrace):
|
|
|
45
54
|
name: str,
|
|
46
55
|
queue_manager: Optional[TraceQueueManager] = None,
|
|
47
56
|
trace_id: Optional[str] = None,
|
|
48
|
-
|
|
49
|
-
|
|
57
|
+
span_id: Optional[str] = None,
|
|
58
|
+
span_type: SpanTypeLiterals = "TRACER",
|
|
59
|
+
input: Optional[SpanInputParam] = None,
|
|
60
|
+
output: Optional[SpanOutputParam] = None,
|
|
61
|
+
metadata: Optional[SpanMetadataParam] = None,
|
|
50
62
|
):
|
|
51
63
|
super().__init__(queue_manager, trace_id)
|
|
52
64
|
|
|
53
65
|
self.root_span = NoOpSpan(
|
|
54
66
|
name=name,
|
|
55
|
-
span_id=
|
|
67
|
+
span_id=span_id,
|
|
56
68
|
trace_id=self.trace_id,
|
|
57
69
|
queue_manager=queue_manager,
|
|
58
70
|
metadata=metadata,
|
|
59
|
-
span_type=
|
|
71
|
+
span_type=span_type,
|
|
72
|
+
input=input,
|
|
73
|
+
output=output,
|
|
74
|
+
)
|
|
75
|
+
|
|
76
|
+
@override
|
|
77
|
+
def __repr__(self) -> str:
|
|
78
|
+
return (
|
|
79
|
+
f"{self.__class__.__name__}("
|
|
80
|
+
f"trace_id='{self.trace_id}', "
|
|
81
|
+
f"root_span='{repr(self.root_span)}', "
|
|
82
|
+
")"
|
|
60
83
|
)
|
|
61
84
|
|
|
62
85
|
@override
|
|
@@ -74,19 +97,24 @@ class Trace(BaseTrace):
|
|
|
74
97
|
name: str,
|
|
75
98
|
queue_manager: TraceQueueManager,
|
|
76
99
|
trace_id: Optional[str] = None,
|
|
77
|
-
|
|
78
|
-
|
|
100
|
+
span_id: Optional[str] = None,
|
|
101
|
+
span_type: SpanTypeLiterals = "TRACER",
|
|
102
|
+
input: Optional[SpanInputParam] = None,
|
|
103
|
+
output: Optional[SpanOutputParam] = None,
|
|
104
|
+
metadata: Optional[SpanMetadataParam] = None,
|
|
79
105
|
):
|
|
80
106
|
super().__init__(queue_manager, trace_id)
|
|
81
107
|
self.queue_manager: TraceQueueManager = queue_manager
|
|
82
108
|
|
|
83
109
|
self.root_span = Span(
|
|
84
110
|
name=name,
|
|
85
|
-
span_id=
|
|
111
|
+
span_id=span_id,
|
|
86
112
|
trace_id=self.trace_id,
|
|
87
113
|
queue_manager=queue_manager,
|
|
88
114
|
metadata=metadata,
|
|
89
|
-
span_type=
|
|
115
|
+
span_type=span_type,
|
|
116
|
+
input=input,
|
|
117
|
+
output=output,
|
|
90
118
|
)
|
|
91
119
|
|
|
92
120
|
@override
|
|
@@ -116,3 +144,12 @@ class Trace(BaseTrace):
|
|
|
116
144
|
self._contextvar_token = None
|
|
117
145
|
|
|
118
146
|
self.root_span.end()
|
|
147
|
+
|
|
148
|
+
@override
|
|
149
|
+
def __repr__(self) -> str:
|
|
150
|
+
return (
|
|
151
|
+
f"{self.__class__.__name__}("
|
|
152
|
+
f"trace_id='{self.trace_id}', "
|
|
153
|
+
f"root_span='{repr(self.root_span)}', "
|
|
154
|
+
")"
|
|
155
|
+
)
|
|
@@ -34,12 +34,22 @@ class TraceExporter:
|
|
|
34
34
|
self.backoff = backoff
|
|
35
35
|
self.max_backoff = max_backoff
|
|
36
36
|
|
|
37
|
+
def export_span(self, client: SGPClient, span: "Span") -> None:
|
|
38
|
+
# only upsert endpoint is batch upsert, so we work in batches
|
|
39
|
+
batch: SpanRequestBatch = self._create_one_span_batch(span)
|
|
40
|
+
|
|
41
|
+
log.info(f"Exporting single span with id {span.span_id}")
|
|
42
|
+
self._export_batch(batch, client)
|
|
43
|
+
|
|
37
44
|
def export(self, client: SGPClient, queue: "Queue[Span]") -> None:
|
|
38
|
-
# export finished spans, note we do a check to ensure spans are finished in spans.py #to_request_params()
|
|
39
45
|
# this is also thread safe, two threads can call this method with the same queue at once
|
|
40
46
|
# the ordering of the requests might be randomly split between the two threads, but they should all be picked up
|
|
41
47
|
batches: list[SpanRequestBatch] = self._create_batches(queue)
|
|
42
48
|
|
|
49
|
+
if not batches:
|
|
50
|
+
log.debug("No new span batches to export")
|
|
51
|
+
return
|
|
52
|
+
|
|
43
53
|
log.info(f"Exporting {len(batches)} span batches")
|
|
44
54
|
|
|
45
55
|
for batch in batches:
|
|
@@ -74,15 +84,25 @@ class TraceExporter:
|
|
|
74
84
|
while len(span_batch) < self.max_batch_size and queue.qsize() > 0:
|
|
75
85
|
try:
|
|
76
86
|
span: "Span" = queue.get_nowait()
|
|
77
|
-
|
|
78
|
-
span_batch.append(span_request)
|
|
87
|
+
self._add_span_to_batch(span, span_batch)
|
|
79
88
|
except Empty:
|
|
80
89
|
break
|
|
81
|
-
except ParamsCreationError as e:
|
|
82
|
-
log.warning(f"ParamsCreationError: {e}\ndropping...")
|
|
83
90
|
|
|
84
91
|
if not span_batch:
|
|
85
92
|
break
|
|
86
93
|
batches.append(span_batch)
|
|
87
94
|
|
|
88
95
|
return batches
|
|
96
|
+
|
|
97
|
+
def _create_one_span_batch(self, span: "Span") -> SpanRequestBatch:
|
|
98
|
+
span_batch: SpanRequestBatch = []
|
|
99
|
+
self._add_span_to_batch(span, span_batch)
|
|
100
|
+
|
|
101
|
+
return span_batch
|
|
102
|
+
|
|
103
|
+
def _add_span_to_batch(self, span: "Span", span_batch: SpanRequestBatch) -> None:
|
|
104
|
+
try:
|
|
105
|
+
span_request = span.to_request_params()
|
|
106
|
+
span_batch.append(span_request)
|
|
107
|
+
except ParamsCreationError as e:
|
|
108
|
+
log.warning(f"ParamsCreationError: dropping span: {span}\n{e}")
|
|
@@ -76,16 +76,10 @@ class TraceQueueManager:
|
|
|
76
76
|
|
|
77
77
|
def report_span_start(self, span: "Span") -> None:
|
|
78
78
|
# TODO: support making this optional. Current backend requires us to send span starts
|
|
79
|
-
|
|
80
|
-
self._queue.put_nowait(span)
|
|
81
|
-
except queue.Full:
|
|
82
|
-
log.warning(f"Queue full, ignoring span {span.span_id}")
|
|
79
|
+
self.enqueue(span)
|
|
83
80
|
|
|
84
81
|
def report_span_end(self, span: "Span") -> None:
|
|
85
|
-
|
|
86
|
-
self._queue.put_nowait(span)
|
|
87
|
-
except queue.Full:
|
|
88
|
-
log.warning(f"Queue full, ignoring span {span.span_id}")
|
|
82
|
+
self.enqueue(span)
|
|
89
83
|
|
|
90
84
|
def report_trace_start(self, trace: "Trace") -> None:
|
|
91
85
|
pass
|
|
@@ -96,6 +90,16 @@ class TraceQueueManager:
|
|
|
96
90
|
def flush_queue(self) -> None:
|
|
97
91
|
self._export()
|
|
98
92
|
|
|
93
|
+
def enqueue(self, span: "Span") -> None:
|
|
94
|
+
try:
|
|
95
|
+
self._queue.put_nowait(span)
|
|
96
|
+
except queue.Full:
|
|
97
|
+
log.warning(f"Queue full, ignoring span {span.span_id}")
|
|
98
|
+
|
|
99
|
+
def export_now(self, span: "Span") -> None:
|
|
100
|
+
if self.client:
|
|
101
|
+
self._exporter.export_span(self.client, span)
|
|
102
|
+
|
|
99
103
|
@property
|
|
100
104
|
def client(self) -> Optional[SGPClient]:
|
|
101
105
|
"""
|
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
import logging
|
|
2
|
-
from typing import
|
|
2
|
+
from typing import Optional
|
|
3
3
|
|
|
4
4
|
from .span import Span, BaseSpan, NoOpSpan
|
|
5
5
|
from .util import is_disabled
|
|
6
6
|
from .scope import Scope
|
|
7
7
|
from .trace import Trace, BaseTrace, NoOpTrace
|
|
8
|
+
from .types import SpanInputParam, SpanOutputParam, SpanTypeLiterals, SpanMetadataParam
|
|
8
9
|
from .trace_queue_manager import tracing_queue_manager
|
|
9
10
|
|
|
10
11
|
log: logging.Logger = logging.getLogger(__name__)
|
|
@@ -50,9 +51,12 @@ def flush_queue() -> None:
|
|
|
50
51
|
|
|
51
52
|
def create_trace(
|
|
52
53
|
name: str,
|
|
54
|
+
span_type: SpanTypeLiterals = "TRACER",
|
|
55
|
+
input: Optional[SpanInputParam] = None,
|
|
56
|
+
output: Optional[SpanOutputParam] = None,
|
|
57
|
+
metadata: Optional[SpanMetadataParam] = None,
|
|
58
|
+
span_id: Optional[str] = None,
|
|
53
59
|
trace_id: Optional[str] = None,
|
|
54
|
-
root_span_id: Optional[str] = None,
|
|
55
|
-
metadata: Optional[Dict[str, Optional[str]]] = None,
|
|
56
60
|
) -> BaseTrace:
|
|
57
61
|
"""Creates a new trace and root span instance.
|
|
58
62
|
|
|
@@ -68,24 +72,51 @@ def create_trace(
|
|
|
68
72
|
|
|
69
73
|
Args:
|
|
70
74
|
name: The name of the trace.
|
|
75
|
+
span_type (Optional[SpanTypeLiterals]): Type of root span.
|
|
76
|
+
input (Optional[SpanInputParam]): Input of root span.
|
|
77
|
+
output (Optional[SpanOutputParam]): Output of root span.
|
|
78
|
+
metadata (Optional[SpanMetadataParam]): An optional, user-defined metadata.
|
|
79
|
+
span_id (Optional[str]): An optional, user-defined ID for the root span.
|
|
80
|
+
Max length is 38 characters.
|
|
71
81
|
trace_id (Optional[str]): An optional, user-defined ID for the trace.
|
|
72
82
|
If None, a unique trace ID will be generated.
|
|
73
|
-
|
|
74
|
-
metadata (Optional[Dict[str, Optional[str]]]): An optional, user-defined metadata.
|
|
83
|
+
Max length is 38 characters.
|
|
75
84
|
|
|
76
85
|
Returns:
|
|
77
86
|
BaseTrace: A `Trace` instance if tracing is enabled, or a `NoOpTrace`
|
|
78
87
|
instance if tracing is disabled.
|
|
79
88
|
"""
|
|
89
|
+
impl_input: SpanInputParam = input or {}
|
|
90
|
+
impl_output: SpanOutputParam = output or {}
|
|
91
|
+
impl_metadata: SpanMetadataParam = metadata or {}
|
|
92
|
+
|
|
80
93
|
if is_disabled():
|
|
81
94
|
log.debug(f"Tracing is disabled. Not creating a new trace.")
|
|
82
|
-
return NoOpTrace(
|
|
95
|
+
return NoOpTrace(
|
|
96
|
+
name=name,
|
|
97
|
+
trace_id=trace_id,
|
|
98
|
+
span_id=span_id,
|
|
99
|
+
span_type=span_type,
|
|
100
|
+
input=impl_input,
|
|
101
|
+
output=impl_output,
|
|
102
|
+
metadata=impl_metadata,
|
|
103
|
+
)
|
|
83
104
|
|
|
84
105
|
active_trace = current_trace()
|
|
85
106
|
if active_trace is not None:
|
|
86
107
|
log.warning(f"Trace with id {active_trace.trace_id} is already active. Creating a new trace anyways.")
|
|
87
108
|
|
|
88
|
-
|
|
109
|
+
queue_manager = tracing_queue_manager()
|
|
110
|
+
trace = Trace(
|
|
111
|
+
name=name,
|
|
112
|
+
trace_id=trace_id,
|
|
113
|
+
span_id=span_id,
|
|
114
|
+
queue_manager=queue_manager,
|
|
115
|
+
span_type=span_type,
|
|
116
|
+
input=impl_input,
|
|
117
|
+
output=impl_output,
|
|
118
|
+
metadata=impl_metadata,
|
|
119
|
+
)
|
|
89
120
|
log.debug(f"Created new trace: {trace.trace_id}")
|
|
90
121
|
|
|
91
122
|
return trace
|
|
@@ -93,12 +124,13 @@ def create_trace(
|
|
|
93
124
|
|
|
94
125
|
def create_span(
|
|
95
126
|
name: str,
|
|
127
|
+
span_type: SpanTypeLiterals = "STANDALONE",
|
|
128
|
+
input: Optional[SpanInputParam] = None,
|
|
129
|
+
output: Optional[SpanOutputParam] = None,
|
|
130
|
+
metadata: Optional[SpanMetadataParam] = None,
|
|
96
131
|
span_id: Optional[str] = None,
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
metadata: Optional[Dict[str, Optional[str]]] = None,
|
|
100
|
-
trace: Optional[Union[BaseTrace, str]] = None,
|
|
101
|
-
parent_span: Optional[BaseSpan] = None,
|
|
132
|
+
parent_id: Optional[str] = None,
|
|
133
|
+
trace_id: Optional[str] = None,
|
|
102
134
|
) -> BaseSpan:
|
|
103
135
|
"""Creates a new span instance.
|
|
104
136
|
|
|
@@ -113,67 +145,75 @@ def create_span(
|
|
|
113
145
|
When a span is started (e.g., via context manager or `start()`), it becomes
|
|
114
146
|
the `current_span()` in the active scope.
|
|
115
147
|
|
|
148
|
+
If explicitly setting 'parent_id' and 'trace_id', ensure that the parent span
|
|
149
|
+
has the same 'trace_id'.
|
|
150
|
+
|
|
116
151
|
Args:
|
|
117
152
|
name (str): A descriptive name for the span (e.g., "database_query",
|
|
118
153
|
"http_request").
|
|
119
|
-
|
|
120
|
-
input (Optional[
|
|
154
|
+
span_type (SpanTypeLiterals): The type of the span.
|
|
155
|
+
input (Optional[SpanInputParam], optional): A dictionary containing
|
|
121
156
|
input data or parameters relevant to this span's operation. Defaults to None.
|
|
122
|
-
output (Optional[
|
|
157
|
+
output (Optional[SpanOutputParam], optional): A dictionary containing
|
|
123
158
|
output data or results from this span's operation. Defaults to None.
|
|
124
|
-
metadata (Optional[
|
|
159
|
+
metadata (Optional[SpanMetadataParam], optional):
|
|
125
160
|
A dictionary for arbitrary key-value pairs providing additional
|
|
126
161
|
context or annotations for the span. Values should be simple types.
|
|
127
162
|
Defaults to None.
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
active scope.
|
|
163
|
+
span_id (Optional[str]): An optional, user-defined ID for the span.
|
|
164
|
+
parent_id (Optional[str], optional): A `Span` id. Used for explicit control.
|
|
165
|
+
Defaults to span id fetched from the active scope.
|
|
166
|
+
trace_id (Optional[str], optional): A `Trace` id. Used for explicit control.
|
|
167
|
+
Default to trace id fetched from the active scope.
|
|
134
168
|
|
|
135
169
|
Returns:
|
|
136
170
|
BaseSpan: A `Span` instance if tracing is enabled and a valid trace context
|
|
137
171
|
exists, or a `NoOpSpan` otherwise.
|
|
138
172
|
"""
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
if parent_span is not None:
|
|
143
|
-
trace_id = parent_span.trace_id
|
|
144
|
-
parent_span_id = parent_span.span_id
|
|
145
|
-
elif trace is not None:
|
|
146
|
-
trace_id = trace if isinstance(trace, str) else trace.trace_id
|
|
173
|
+
impl_input: SpanInputParam = input or {}
|
|
174
|
+
impl_output: SpanOutputParam = output or {}
|
|
175
|
+
impl_metadata: SpanMetadataParam = metadata or {}
|
|
147
176
|
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
parent_span = Scope.get_current_span()
|
|
177
|
+
scoped_trace = current_trace()
|
|
178
|
+
scoped_trace_id = scoped_trace.trace_id if scoped_trace else None
|
|
179
|
+
scoped_span = current_span()
|
|
180
|
+
scoped_span_id = scoped_span.span_id if scoped_span else None
|
|
153
181
|
|
|
154
|
-
|
|
182
|
+
parent_span_id: Optional[str] = parent_id or scoped_span_id
|
|
183
|
+
# TODO: preference should be trace_id -> trace_id from parent span if parent_id present -> scoped_trace_id
|
|
184
|
+
impl_trace_id: Optional[str] = trace_id or scoped_trace_id
|
|
155
185
|
|
|
156
|
-
|
|
157
|
-
# need to think about default behavior here... do we create a trace, some other options?
|
|
158
|
-
# I am leaning towards setting it as an option as sometimes people might want to be succinct or when we
|
|
159
|
-
# build decorators we might want this functionality
|
|
160
|
-
log.debug(f"attempting to create a span with no trace")
|
|
161
|
-
return NoOpSpan(name=name, span_id=span_id, parent_span_id=parent_span_id)
|
|
186
|
+
# TODO: do a check to ensure trace_id of parent_span matches trace_id (when trace_id is specified)
|
|
162
187
|
|
|
163
|
-
|
|
188
|
+
noop_span = NoOpSpan(
|
|
189
|
+
name=name,
|
|
190
|
+
span_id=span_id,
|
|
191
|
+
parent_span_id=parent_span_id,
|
|
192
|
+
trace_id=impl_trace_id,
|
|
193
|
+
input=impl_input,
|
|
194
|
+
output=impl_output,
|
|
195
|
+
metadata=impl_metadata,
|
|
196
|
+
span_type=span_type,
|
|
197
|
+
)
|
|
164
198
|
|
|
165
199
|
if is_disabled():
|
|
166
|
-
return
|
|
200
|
+
return noop_span
|
|
201
|
+
|
|
202
|
+
if impl_trace_id is None:
|
|
203
|
+
log.debug(f"Attempting to create a span with no trace")
|
|
204
|
+
return noop_span
|
|
167
205
|
|
|
206
|
+
queue_manager = tracing_queue_manager()
|
|
168
207
|
span = Span(
|
|
169
208
|
name=name,
|
|
170
209
|
span_id=span_id,
|
|
171
210
|
parent_span_id=parent_span_id,
|
|
172
|
-
trace_id=
|
|
173
|
-
input=
|
|
174
|
-
output=
|
|
175
|
-
metadata=
|
|
211
|
+
trace_id=impl_trace_id,
|
|
212
|
+
input=impl_input,
|
|
213
|
+
output=impl_output,
|
|
214
|
+
metadata=impl_metadata,
|
|
176
215
|
queue_manager=queue_manager,
|
|
216
|
+
span_type=span_type,
|
|
177
217
|
)
|
|
178
218
|
log.debug(f"Created new span: {span.span_id}")
|
|
179
219
|
|
|
@@ -1,12 +1,17 @@
|
|
|
1
1
|
"""
|
|
2
|
-
This is necessary, unfortunately. Stainless does not provide
|
|
2
|
+
This is necessary, unfortunately. Stainless does not provide SpanStatusLiterals and SpanTypeLiterals as enums, only as
|
|
3
|
+
type annotations.
|
|
3
4
|
|
|
4
5
|
For strict linting, we need to reference these enums.
|
|
5
6
|
|
|
6
7
|
NOTE: These will have to be manually updated to support updated span_types and status.
|
|
7
8
|
"""
|
|
8
9
|
|
|
9
|
-
from typing_extensions import Literal
|
|
10
|
+
from typing_extensions import Any, Dict, Literal
|
|
11
|
+
|
|
12
|
+
SpanInputParam = Dict[str, Any]
|
|
13
|
+
SpanOutputParam = Dict[str, Any]
|
|
14
|
+
SpanMetadataParam = Dict[str, Any]
|
|
10
15
|
|
|
11
16
|
SpanStatusLiterals = Literal["SUCCESS", "ERROR"]
|
|
12
17
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.3
|
|
2
2
|
Name: scale-gp-beta
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.0a20
|
|
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
|
|
@@ -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=6UZbVIfacMp5Bp3n8ioyF0Rlmq1dDufS-TfPMR72s4w,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,12 +28,12 @@ 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=
|
|
33
|
-
scale_gp_beta/lib/tracing/trace_exporter.py,sha256=
|
|
34
|
-
scale_gp_beta/lib/tracing/trace_queue_manager.py,sha256=
|
|
35
|
-
scale_gp_beta/lib/tracing/tracing.py,sha256=
|
|
36
|
-
scale_gp_beta/lib/tracing/types.py,sha256=
|
|
31
|
+
scale_gp_beta/lib/tracing/span.py,sha256=RBTpNPxwmovcC3OzyApNbgnK2mA5kv8Ml6LH89dQsbg,9456
|
|
32
|
+
scale_gp_beta/lib/tracing/trace.py,sha256=iArpvjoJd8_lxSKi5CJ1Gw_VIpJo4qQoBWv4yT2KHOs,4501
|
|
33
|
+
scale_gp_beta/lib/tracing/trace_exporter.py,sha256=bE6hS-Qu9KknEUTdsfIQMQwauah125mEavTDqEenBRA,3779
|
|
34
|
+
scale_gp_beta/lib/tracing/trace_queue_manager.py,sha256=xywP3myhaHX52i52ZfC2_-ONrd-4_aL-f3-3jNhh2XY,5961
|
|
35
|
+
scale_gp_beta/lib/tracing/tracing.py,sha256=94WJrqIxU1iFtF8CGsD2uvrJ1AnY9RgpW-wNTNHSvYg,8254
|
|
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
|
|
39
39
|
scale_gp_beta/resources/completions.py,sha256=4esj9lGTJAxt6wFvON126DvEGkMIChRZ6uZBOf56Aac,31868
|
|
@@ -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.0a20.dist-info/METADATA,sha256=Vq4QI-Qk5UHS52GDxna_KAZ1Bd3PzxoewR2c_RtaMJk,16881
|
|
121
|
+
scale_gp_beta-0.1.0a20.dist-info/WHEEL,sha256=C2FUgwZgiLbznR-k0b_5k3Ai_1aASOXDss3lzCUsUug,87
|
|
122
|
+
scale_gp_beta-0.1.0a20.dist-info/licenses/LICENSE,sha256=x49Bj8r_ZpqfzThbmfHyZ_bE88XvHdIMI_ANyLHFFRE,11338
|
|
123
|
+
scale_gp_beta-0.1.0a20.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|