scale-gp-beta 0.1.0a23__py3-none-any.whl → 0.1.0a25__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/__init__.py +2 -1
- scale_gp_beta/_base_client.py +22 -0
- scale_gp_beta/_client.py +19 -1
- scale_gp_beta/_version.py +1 -1
- scale_gp_beta/lib/tracing/span.py +84 -53
- scale_gp_beta/lib/tracing/trace_queue_manager.py +7 -3
- scale_gp_beta/lib/tracing/tracing.py +9 -3
- scale_gp_beta/lib/tracing/types.py +1 -3
- scale_gp_beta/resources/__init__.py +14 -0
- scale_gp_beta/resources/chat/completions.py +4 -2
- scale_gp_beta/resources/models.py +2 -0
- scale_gp_beta/resources/questions.py +693 -0
- scale_gp_beta/resources/spans.py +124 -92
- scale_gp_beta/types/__init__.py +4 -1
- scale_gp_beta/types/chat/chat_completion.py +1 -1
- scale_gp_beta/types/chat/chat_completion_chunk.py +1 -1
- scale_gp_beta/types/chat/completion_models_params.py +1 -0
- scale_gp_beta/types/chat/model_definition.py +1 -0
- scale_gp_beta/types/inference_model.py +1 -0
- scale_gp_beta/types/model_list_params.py +1 -0
- scale_gp_beta/types/question.py +175 -0
- scale_gp_beta/types/question_create_params.py +121 -0
- scale_gp_beta/types/{span_search_response.py → question_list.py} +4 -4
- scale_gp_beta/types/question_list_params.py +17 -0
- scale_gp_beta/types/span.py +1 -3
- scale_gp_beta/types/span_batch_params.py +1 -3
- scale_gp_beta/types/span_create_params.py +1 -3
- scale_gp_beta/types/span_search_params.py +45 -33
- scale_gp_beta/types/span_update_params.py +1 -1
- scale_gp_beta/types/span_upsert_batch_params.py +1 -3
- {scale_gp_beta-0.1.0a23.dist-info → scale_gp_beta-0.1.0a25.dist-info}/METADATA +41 -1
- {scale_gp_beta-0.1.0a23.dist-info → scale_gp_beta-0.1.0a25.dist-info}/RECORD +34 -30
- {scale_gp_beta-0.1.0a23.dist-info → scale_gp_beta-0.1.0a25.dist-info}/WHEEL +0 -0
- {scale_gp_beta-0.1.0a23.dist-info → scale_gp_beta-0.1.0a25.dist-info}/licenses/LICENSE +0 -0
scale_gp_beta/__init__.py
CHANGED
|
@@ -37,7 +37,7 @@ from ._exceptions import (
|
|
|
37
37
|
UnprocessableEntityError,
|
|
38
38
|
APIResponseValidationError,
|
|
39
39
|
)
|
|
40
|
-
from ._base_client import DefaultHttpxClient, DefaultAsyncHttpxClient
|
|
40
|
+
from ._base_client import DefaultHttpxClient, DefaultAioHttpClient, DefaultAsyncHttpxClient
|
|
41
41
|
from ._utils._logs import setup_logging as _setup_logging
|
|
42
42
|
|
|
43
43
|
__all__ = [
|
|
@@ -80,6 +80,7 @@ __all__ = [
|
|
|
80
80
|
"DEFAULT_CONNECTION_LIMITS",
|
|
81
81
|
"DefaultHttpxClient",
|
|
82
82
|
"DefaultAsyncHttpxClient",
|
|
83
|
+
"DefaultAioHttpClient",
|
|
83
84
|
]
|
|
84
85
|
|
|
85
86
|
if not _t.TYPE_CHECKING:
|
scale_gp_beta/_base_client.py
CHANGED
|
@@ -1289,6 +1289,24 @@ class _DefaultAsyncHttpxClient(httpx.AsyncClient):
|
|
|
1289
1289
|
super().__init__(**kwargs)
|
|
1290
1290
|
|
|
1291
1291
|
|
|
1292
|
+
try:
|
|
1293
|
+
import httpx_aiohttp
|
|
1294
|
+
except ImportError:
|
|
1295
|
+
|
|
1296
|
+
class _DefaultAioHttpClient(httpx.AsyncClient):
|
|
1297
|
+
def __init__(self, **_kwargs: Any) -> None:
|
|
1298
|
+
raise RuntimeError("To use the aiohttp client you must have installed the package with the `aiohttp` extra")
|
|
1299
|
+
else:
|
|
1300
|
+
|
|
1301
|
+
class _DefaultAioHttpClient(httpx_aiohttp.HttpxAiohttpClient): # type: ignore
|
|
1302
|
+
def __init__(self, **kwargs: Any) -> None:
|
|
1303
|
+
kwargs.setdefault("timeout", DEFAULT_TIMEOUT)
|
|
1304
|
+
kwargs.setdefault("limits", DEFAULT_CONNECTION_LIMITS)
|
|
1305
|
+
kwargs.setdefault("follow_redirects", True)
|
|
1306
|
+
|
|
1307
|
+
super().__init__(**kwargs)
|
|
1308
|
+
|
|
1309
|
+
|
|
1292
1310
|
if TYPE_CHECKING:
|
|
1293
1311
|
DefaultAsyncHttpxClient = httpx.AsyncClient
|
|
1294
1312
|
"""An alias to `httpx.AsyncClient` that provides the same defaults that this SDK
|
|
@@ -1297,8 +1315,12 @@ if TYPE_CHECKING:
|
|
|
1297
1315
|
This is useful because overriding the `http_client` with your own instance of
|
|
1298
1316
|
`httpx.AsyncClient` will result in httpx's defaults being used, not ours.
|
|
1299
1317
|
"""
|
|
1318
|
+
|
|
1319
|
+
DefaultAioHttpClient = httpx.AsyncClient
|
|
1320
|
+
"""An alias to `httpx.AsyncClient` that changes the default HTTP transport to `aiohttp`."""
|
|
1300
1321
|
else:
|
|
1301
1322
|
DefaultAsyncHttpxClient = _DefaultAsyncHttpxClient
|
|
1323
|
+
DefaultAioHttpClient = _DefaultAioHttpClient
|
|
1302
1324
|
|
|
1303
1325
|
|
|
1304
1326
|
class AsyncHttpxClientWrapper(DefaultAsyncHttpxClient):
|
scale_gp_beta/_client.py
CHANGED
|
@@ -21,7 +21,17 @@ from ._types import (
|
|
|
21
21
|
)
|
|
22
22
|
from ._utils import is_given, get_async_library
|
|
23
23
|
from ._version import __version__
|
|
24
|
-
from .resources import
|
|
24
|
+
from .resources import (
|
|
25
|
+
spans,
|
|
26
|
+
models,
|
|
27
|
+
datasets,
|
|
28
|
+
inference,
|
|
29
|
+
questions,
|
|
30
|
+
completions,
|
|
31
|
+
evaluations,
|
|
32
|
+
dataset_items,
|
|
33
|
+
evaluation_items,
|
|
34
|
+
)
|
|
25
35
|
from ._streaming import Stream as Stream, AsyncStream as AsyncStream
|
|
26
36
|
from ._exceptions import APIStatusError, SGPClientError
|
|
27
37
|
from ._base_client import (
|
|
@@ -54,6 +64,7 @@ class SGPClient(SyncAPIClient):
|
|
|
54
64
|
completions: completions.CompletionsResource
|
|
55
65
|
chat: chat.ChatResource
|
|
56
66
|
inference: inference.InferenceResource
|
|
67
|
+
questions: questions.QuestionsResource
|
|
57
68
|
files: files.FilesResource
|
|
58
69
|
models: models.ModelsResource
|
|
59
70
|
datasets: datasets.DatasetsResource
|
|
@@ -157,6 +168,7 @@ class SGPClient(SyncAPIClient):
|
|
|
157
168
|
self.completions = completions.CompletionsResource(self)
|
|
158
169
|
self.chat = chat.ChatResource(self)
|
|
159
170
|
self.inference = inference.InferenceResource(self)
|
|
171
|
+
self.questions = questions.QuestionsResource(self)
|
|
160
172
|
self.files = files.FilesResource(self)
|
|
161
173
|
self.models = models.ModelsResource(self)
|
|
162
174
|
self.datasets = datasets.DatasetsResource(self)
|
|
@@ -281,6 +293,7 @@ class AsyncSGPClient(AsyncAPIClient):
|
|
|
281
293
|
completions: completions.AsyncCompletionsResource
|
|
282
294
|
chat: chat.AsyncChatResource
|
|
283
295
|
inference: inference.AsyncInferenceResource
|
|
296
|
+
questions: questions.AsyncQuestionsResource
|
|
284
297
|
files: files.AsyncFilesResource
|
|
285
298
|
models: models.AsyncModelsResource
|
|
286
299
|
datasets: datasets.AsyncDatasetsResource
|
|
@@ -384,6 +397,7 @@ class AsyncSGPClient(AsyncAPIClient):
|
|
|
384
397
|
self.completions = completions.AsyncCompletionsResource(self)
|
|
385
398
|
self.chat = chat.AsyncChatResource(self)
|
|
386
399
|
self.inference = inference.AsyncInferenceResource(self)
|
|
400
|
+
self.questions = questions.AsyncQuestionsResource(self)
|
|
387
401
|
self.files = files.AsyncFilesResource(self)
|
|
388
402
|
self.models = models.AsyncModelsResource(self)
|
|
389
403
|
self.datasets = datasets.AsyncDatasetsResource(self)
|
|
@@ -509,6 +523,7 @@ class SGPClientWithRawResponse:
|
|
|
509
523
|
self.completions = completions.CompletionsResourceWithRawResponse(client.completions)
|
|
510
524
|
self.chat = chat.ChatResourceWithRawResponse(client.chat)
|
|
511
525
|
self.inference = inference.InferenceResourceWithRawResponse(client.inference)
|
|
526
|
+
self.questions = questions.QuestionsResourceWithRawResponse(client.questions)
|
|
512
527
|
self.files = files.FilesResourceWithRawResponse(client.files)
|
|
513
528
|
self.models = models.ModelsResourceWithRawResponse(client.models)
|
|
514
529
|
self.datasets = datasets.DatasetsResourceWithRawResponse(client.datasets)
|
|
@@ -523,6 +538,7 @@ class AsyncSGPClientWithRawResponse:
|
|
|
523
538
|
self.completions = completions.AsyncCompletionsResourceWithRawResponse(client.completions)
|
|
524
539
|
self.chat = chat.AsyncChatResourceWithRawResponse(client.chat)
|
|
525
540
|
self.inference = inference.AsyncInferenceResourceWithRawResponse(client.inference)
|
|
541
|
+
self.questions = questions.AsyncQuestionsResourceWithRawResponse(client.questions)
|
|
526
542
|
self.files = files.AsyncFilesResourceWithRawResponse(client.files)
|
|
527
543
|
self.models = models.AsyncModelsResourceWithRawResponse(client.models)
|
|
528
544
|
self.datasets = datasets.AsyncDatasetsResourceWithRawResponse(client.datasets)
|
|
@@ -537,6 +553,7 @@ class SGPClientWithStreamedResponse:
|
|
|
537
553
|
self.completions = completions.CompletionsResourceWithStreamingResponse(client.completions)
|
|
538
554
|
self.chat = chat.ChatResourceWithStreamingResponse(client.chat)
|
|
539
555
|
self.inference = inference.InferenceResourceWithStreamingResponse(client.inference)
|
|
556
|
+
self.questions = questions.QuestionsResourceWithStreamingResponse(client.questions)
|
|
540
557
|
self.files = files.FilesResourceWithStreamingResponse(client.files)
|
|
541
558
|
self.models = models.ModelsResourceWithStreamingResponse(client.models)
|
|
542
559
|
self.datasets = datasets.DatasetsResourceWithStreamingResponse(client.datasets)
|
|
@@ -551,6 +568,7 @@ class AsyncSGPClientWithStreamedResponse:
|
|
|
551
568
|
self.completions = completions.AsyncCompletionsResourceWithStreamingResponse(client.completions)
|
|
552
569
|
self.chat = chat.AsyncChatResourceWithStreamingResponse(client.chat)
|
|
553
570
|
self.inference = inference.AsyncInferenceResourceWithStreamingResponse(client.inference)
|
|
571
|
+
self.questions = questions.AsyncQuestionsResourceWithStreamingResponse(client.questions)
|
|
554
572
|
self.files = files.AsyncFilesResourceWithStreamingResponse(client.files)
|
|
555
573
|
self.models = models.AsyncModelsResourceWithStreamingResponse(client.models)
|
|
556
574
|
self.datasets = datasets.AsyncDatasetsResourceWithStreamingResponse(client.datasets)
|
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
|
|
@@ -64,8 +66,8 @@ class BaseSpan:
|
|
|
64
66
|
self._group_id = group_id
|
|
65
67
|
self._span_id: str = span_id or generate_span_id()
|
|
66
68
|
self._parent_span_id = parent_span_id
|
|
67
|
-
self.
|
|
68
|
-
self.
|
|
69
|
+
self._start_time: Optional[str] = None
|
|
70
|
+
self._end_time: Optional[str] = None
|
|
69
71
|
self._input: SpanInputParam = input or {}
|
|
70
72
|
self._output: SpanOutputParam = output or {}
|
|
71
73
|
self._metadata: SpanMetadataParam = metadata or {}
|
|
@@ -74,6 +76,7 @@ class BaseSpan:
|
|
|
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
|
|
@@ -113,13 +116,33 @@ class BaseSpan:
|
|
|
113
116
|
return self._span_type
|
|
114
117
|
|
|
115
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
|
+
|
|
116
137
|
@property
|
|
117
138
|
def metadata(self) -> SpanMetadataParam:
|
|
118
139
|
return self._metadata
|
|
119
140
|
|
|
120
141
|
@metadata.setter
|
|
121
142
|
def metadata(self, value: SpanMetadataParam) -> None:
|
|
122
|
-
|
|
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
|
|
123
146
|
|
|
124
147
|
@property
|
|
125
148
|
def input(self) -> SpanInputParam:
|
|
@@ -127,7 +150,8 @@ class BaseSpan:
|
|
|
127
150
|
|
|
128
151
|
@input.setter
|
|
129
152
|
def input(self, value: SpanInputParam) -> None:
|
|
130
|
-
self.
|
|
153
|
+
with self._lock:
|
|
154
|
+
self._input = value
|
|
131
155
|
|
|
132
156
|
@property
|
|
133
157
|
def output(self) -> SpanOutputParam:
|
|
@@ -135,7 +159,8 @@ class BaseSpan:
|
|
|
135
159
|
|
|
136
160
|
@output.setter
|
|
137
161
|
def output(self, value: SpanOutputParam) -> None:
|
|
138
|
-
self.
|
|
162
|
+
with self._lock:
|
|
163
|
+
self._output = value
|
|
139
164
|
|
|
140
165
|
def set_error(
|
|
141
166
|
self,
|
|
@@ -144,12 +169,13 @@ class BaseSpan:
|
|
|
144
169
|
exception: Optional[BaseException] = None,
|
|
145
170
|
) -> None:
|
|
146
171
|
# Naively record details in metadata for now, note that error capture only supported in context manager
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
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
|
|
153
179
|
|
|
154
180
|
def __enter__(self) -> BaseSpan:
|
|
155
181
|
self.start()
|
|
@@ -167,32 +193,35 @@ class BaseSpan:
|
|
|
167
193
|
self.end()
|
|
168
194
|
|
|
169
195
|
def to_request_params(self) -> SpanCreateRequest:
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
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
|
+
)
|
|
184
211
|
|
|
185
|
-
|
|
186
|
-
|
|
212
|
+
if self.end_time is not None:
|
|
213
|
+
request_data["end_timestamp"] = self.end_time
|
|
187
214
|
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
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
|
|
191
218
|
|
|
192
|
-
|
|
193
|
-
|
|
219
|
+
if self.group_id is not None:
|
|
220
|
+
request_data["group_id"] = self.group_id
|
|
194
221
|
|
|
195
|
-
|
|
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
|
|
196
225
|
|
|
197
226
|
@override
|
|
198
227
|
def __repr__(self) -> str:
|
|
@@ -288,13 +317,14 @@ class Span(BaseSpan):
|
|
|
288
317
|
Sets the `start_time`, reports the span start to the `TraceQueueManager`
|
|
289
318
|
, and registers this span as the current span.
|
|
290
319
|
"""
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
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
|
|
294
324
|
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
325
|
+
self.start_time = iso_timestamp()
|
|
326
|
+
self._queue_manager.report_span_start(self)
|
|
327
|
+
self._contextvar_token = Scope.set_current_span(self)
|
|
298
328
|
|
|
299
329
|
@override
|
|
300
330
|
def end(self) -> None:
|
|
@@ -304,19 +334,20 @@ class Span(BaseSpan):
|
|
|
304
334
|
`TraceQueueManager` for queuing and export, and resets this span from the
|
|
305
335
|
`Scope`.
|
|
306
336
|
"""
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
(
|
|
313
|
-
|
|
314
|
-
|
|
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
|
+
)
|
|
315
347
|
)
|
|
316
|
-
|
|
317
|
-
return
|
|
348
|
+
return
|
|
318
349
|
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
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
|
|
@@ -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
|
|
@@ -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,
|
|
@@ -13,7 +13,7 @@ SpanInputParam = Dict[str, Any]
|
|
|
13
13
|
SpanOutputParam = Dict[str, Any]
|
|
14
14
|
SpanMetadataParam = Dict[str, Any]
|
|
15
15
|
|
|
16
|
-
SpanStatusLiterals = Literal["SUCCESS", "ERROR"]
|
|
16
|
+
SpanStatusLiterals = Literal["SUCCESS", "ERROR", "CANCELED"]
|
|
17
17
|
|
|
18
18
|
SpanTypeLiterals = Literal[
|
|
19
19
|
"TEXT_INPUT",
|
|
@@ -30,8 +30,6 @@ SpanTypeLiterals = Literal[
|
|
|
30
30
|
"DOCUMENT_SEARCH",
|
|
31
31
|
"DOCUMENT_PROMPT",
|
|
32
32
|
"CUSTOM",
|
|
33
|
-
"INPUT_GUARDRAIL",
|
|
34
|
-
"OUTPUT_GUARDRAIL",
|
|
35
33
|
"CODE_EXECUTION",
|
|
36
34
|
"DATA_MANIPULATION",
|
|
37
35
|
"EVALUATION",
|
|
@@ -48,6 +48,14 @@ from .inference import (
|
|
|
48
48
|
InferenceResourceWithStreamingResponse,
|
|
49
49
|
AsyncInferenceResourceWithStreamingResponse,
|
|
50
50
|
)
|
|
51
|
+
from .questions import (
|
|
52
|
+
QuestionsResource,
|
|
53
|
+
AsyncQuestionsResource,
|
|
54
|
+
QuestionsResourceWithRawResponse,
|
|
55
|
+
AsyncQuestionsResourceWithRawResponse,
|
|
56
|
+
QuestionsResourceWithStreamingResponse,
|
|
57
|
+
AsyncQuestionsResourceWithStreamingResponse,
|
|
58
|
+
)
|
|
51
59
|
from .completions import (
|
|
52
60
|
CompletionsResource,
|
|
53
61
|
AsyncCompletionsResource,
|
|
@@ -100,6 +108,12 @@ __all__ = [
|
|
|
100
108
|
"AsyncInferenceResourceWithRawResponse",
|
|
101
109
|
"InferenceResourceWithStreamingResponse",
|
|
102
110
|
"AsyncInferenceResourceWithStreamingResponse",
|
|
111
|
+
"QuestionsResource",
|
|
112
|
+
"AsyncQuestionsResource",
|
|
113
|
+
"QuestionsResourceWithRawResponse",
|
|
114
|
+
"AsyncQuestionsResourceWithRawResponse",
|
|
115
|
+
"QuestionsResourceWithStreamingResponse",
|
|
116
|
+
"AsyncQuestionsResourceWithStreamingResponse",
|
|
103
117
|
"FilesResource",
|
|
104
118
|
"AsyncFilesResource",
|
|
105
119
|
"FilesResourceWithRawResponse",
|
|
@@ -536,6 +536,7 @@ class CompletionsResource(SyncAPIResource):
|
|
|
536
536
|
"model_zoo",
|
|
537
537
|
"bedrock",
|
|
538
538
|
"xai",
|
|
539
|
+
"fireworks_ai",
|
|
539
540
|
]
|
|
540
541
|
| NotGiven = NOT_GIVEN,
|
|
541
542
|
sort_order: Literal["asc", "desc"] | NotGiven = NOT_GIVEN,
|
|
@@ -548,7 +549,7 @@ class CompletionsResource(SyncAPIResource):
|
|
|
548
549
|
timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN,
|
|
549
550
|
) -> CompletionModelsResponse:
|
|
550
551
|
"""
|
|
551
|
-
Chat
|
|
552
|
+
List Chat Completion Models
|
|
552
553
|
|
|
553
554
|
Args:
|
|
554
555
|
extra_headers: Send extra headers
|
|
@@ -1090,6 +1091,7 @@ class AsyncCompletionsResource(AsyncAPIResource):
|
|
|
1090
1091
|
"model_zoo",
|
|
1091
1092
|
"bedrock",
|
|
1092
1093
|
"xai",
|
|
1094
|
+
"fireworks_ai",
|
|
1093
1095
|
]
|
|
1094
1096
|
| NotGiven = NOT_GIVEN,
|
|
1095
1097
|
sort_order: Literal["asc", "desc"] | NotGiven = NOT_GIVEN,
|
|
@@ -1102,7 +1104,7 @@ class AsyncCompletionsResource(AsyncAPIResource):
|
|
|
1102
1104
|
timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN,
|
|
1103
1105
|
) -> CompletionModelsResponse:
|
|
1104
1106
|
"""
|
|
1105
|
-
Chat
|
|
1107
|
+
List Chat Completion Models
|
|
1106
1108
|
|
|
1107
1109
|
Args:
|
|
1108
1110
|
extra_headers: Send extra headers
|
|
@@ -317,6 +317,7 @@ class ModelsResource(SyncAPIResource):
|
|
|
317
317
|
"model_zoo",
|
|
318
318
|
"bedrock",
|
|
319
319
|
"xai",
|
|
320
|
+
"fireworks_ai",
|
|
320
321
|
]
|
|
321
322
|
| NotGiven = NOT_GIVEN,
|
|
322
323
|
name: str | NotGiven = NOT_GIVEN,
|
|
@@ -689,6 +690,7 @@ class AsyncModelsResource(AsyncAPIResource):
|
|
|
689
690
|
"model_zoo",
|
|
690
691
|
"bedrock",
|
|
691
692
|
"xai",
|
|
693
|
+
"fireworks_ai",
|
|
692
694
|
]
|
|
693
695
|
| NotGiven = NOT_GIVEN,
|
|
694
696
|
name: str | NotGiven = NOT_GIVEN,
|