arize-phoenix 4.4.4rc5__py3-none-any.whl → 4.5.0__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.
Potentially problematic release.
This version of arize-phoenix might be problematic. Click here for more details.
- {arize_phoenix-4.4.4rc5.dist-info → arize_phoenix-4.5.0.dist-info}/METADATA +5 -5
- {arize_phoenix-4.4.4rc5.dist-info → arize_phoenix-4.5.0.dist-info}/RECORD +56 -117
- {arize_phoenix-4.4.4rc5.dist-info → arize_phoenix-4.5.0.dist-info}/WHEEL +1 -1
- phoenix/__init__.py +27 -0
- phoenix/config.py +7 -21
- phoenix/core/model.py +25 -25
- phoenix/core/model_schema.py +62 -64
- phoenix/core/model_schema_adapter.py +25 -27
- phoenix/db/bulk_inserter.py +14 -54
- phoenix/db/insertion/evaluation.py +6 -6
- phoenix/db/insertion/helpers.py +2 -13
- phoenix/db/migrations/versions/cf03bd6bae1d_init.py +28 -2
- phoenix/db/models.py +4 -236
- phoenix/inferences/fixtures.py +23 -23
- phoenix/inferences/inferences.py +7 -7
- phoenix/inferences/validation.py +1 -1
- phoenix/server/api/context.py +0 -18
- phoenix/server/api/dataloaders/__init__.py +0 -18
- phoenix/server/api/dataloaders/span_descendants.py +3 -2
- phoenix/server/api/routers/v1/__init__.py +2 -77
- phoenix/server/api/routers/v1/evaluations.py +2 -4
- phoenix/server/api/routers/v1/spans.py +1 -3
- phoenix/server/api/routers/v1/traces.py +4 -1
- phoenix/server/api/schema.py +303 -2
- phoenix/server/api/types/Cluster.py +19 -19
- phoenix/server/api/types/Dataset.py +63 -282
- phoenix/server/api/types/DatasetRole.py +23 -0
- phoenix/server/api/types/Dimension.py +29 -30
- phoenix/server/api/types/EmbeddingDimension.py +34 -40
- phoenix/server/api/types/Event.py +16 -16
- phoenix/server/api/{mutations/export_events_mutations.py → types/ExportEventsMutation.py} +14 -17
- phoenix/server/api/types/Model.py +42 -43
- phoenix/server/api/types/Project.py +12 -26
- phoenix/server/api/types/Span.py +2 -79
- phoenix/server/api/types/TimeSeries.py +6 -6
- phoenix/server/api/types/Trace.py +4 -15
- phoenix/server/api/types/UMAPPoints.py +1 -1
- phoenix/server/api/types/node.py +111 -5
- phoenix/server/api/types/pagination.py +52 -10
- phoenix/server/app.py +49 -101
- phoenix/server/main.py +27 -49
- phoenix/server/openapi/docs.py +0 -3
- phoenix/server/static/index.js +2595 -3523
- phoenix/server/templates/index.html +0 -1
- phoenix/services.py +15 -15
- phoenix/session/client.py +21 -438
- phoenix/session/session.py +37 -47
- phoenix/trace/exporter.py +9 -14
- phoenix/trace/fixtures.py +7 -133
- phoenix/trace/schemas.py +2 -1
- phoenix/trace/span_evaluations.py +3 -3
- phoenix/trace/trace_dataset.py +6 -6
- phoenix/version.py +1 -1
- phoenix/datasets/__init__.py +0 -0
- phoenix/datasets/evaluators/__init__.py +0 -18
- phoenix/datasets/evaluators/code_evaluators.py +0 -99
- phoenix/datasets/evaluators/llm_evaluators.py +0 -244
- phoenix/datasets/evaluators/utils.py +0 -292
- phoenix/datasets/experiments.py +0 -550
- phoenix/datasets/tracing.py +0 -85
- phoenix/datasets/types.py +0 -178
- phoenix/db/insertion/dataset.py +0 -237
- phoenix/db/migrations/types.py +0 -29
- phoenix/db/migrations/versions/10460e46d750_datasets.py +0 -291
- phoenix/server/api/dataloaders/dataset_example_revisions.py +0 -100
- phoenix/server/api/dataloaders/dataset_example_spans.py +0 -43
- phoenix/server/api/dataloaders/experiment_annotation_summaries.py +0 -85
- phoenix/server/api/dataloaders/experiment_error_rates.py +0 -43
- phoenix/server/api/dataloaders/experiment_run_counts.py +0 -42
- phoenix/server/api/dataloaders/experiment_sequence_number.py +0 -49
- phoenix/server/api/dataloaders/project_by_name.py +0 -31
- phoenix/server/api/dataloaders/span_projects.py +0 -33
- phoenix/server/api/dataloaders/trace_row_ids.py +0 -39
- phoenix/server/api/helpers/dataset_helpers.py +0 -179
- phoenix/server/api/input_types/AddExamplesToDatasetInput.py +0 -16
- phoenix/server/api/input_types/AddSpansToDatasetInput.py +0 -14
- phoenix/server/api/input_types/ClearProjectInput.py +0 -15
- phoenix/server/api/input_types/CreateDatasetInput.py +0 -12
- phoenix/server/api/input_types/DatasetExampleInput.py +0 -14
- phoenix/server/api/input_types/DatasetSort.py +0 -17
- phoenix/server/api/input_types/DatasetVersionSort.py +0 -16
- phoenix/server/api/input_types/DeleteDatasetExamplesInput.py +0 -13
- phoenix/server/api/input_types/DeleteDatasetInput.py +0 -7
- phoenix/server/api/input_types/DeleteExperimentsInput.py +0 -9
- phoenix/server/api/input_types/PatchDatasetExamplesInput.py +0 -35
- phoenix/server/api/input_types/PatchDatasetInput.py +0 -14
- phoenix/server/api/mutations/__init__.py +0 -13
- phoenix/server/api/mutations/auth.py +0 -11
- phoenix/server/api/mutations/dataset_mutations.py +0 -520
- phoenix/server/api/mutations/experiment_mutations.py +0 -65
- phoenix/server/api/mutations/project_mutations.py +0 -47
- phoenix/server/api/openapi/__init__.py +0 -0
- phoenix/server/api/openapi/main.py +0 -6
- phoenix/server/api/openapi/schema.py +0 -16
- phoenix/server/api/queries.py +0 -503
- phoenix/server/api/routers/v1/dataset_examples.py +0 -178
- phoenix/server/api/routers/v1/datasets.py +0 -965
- phoenix/server/api/routers/v1/experiment_evaluations.py +0 -66
- phoenix/server/api/routers/v1/experiment_runs.py +0 -108
- phoenix/server/api/routers/v1/experiments.py +0 -174
- phoenix/server/api/types/AnnotatorKind.py +0 -10
- phoenix/server/api/types/CreateDatasetPayload.py +0 -8
- phoenix/server/api/types/DatasetExample.py +0 -85
- phoenix/server/api/types/DatasetExampleRevision.py +0 -34
- phoenix/server/api/types/DatasetVersion.py +0 -14
- phoenix/server/api/types/ExampleRevisionInterface.py +0 -14
- phoenix/server/api/types/Experiment.py +0 -140
- phoenix/server/api/types/ExperimentAnnotationSummary.py +0 -13
- phoenix/server/api/types/ExperimentComparison.py +0 -19
- phoenix/server/api/types/ExperimentRun.py +0 -91
- phoenix/server/api/types/ExperimentRunAnnotation.py +0 -57
- phoenix/server/api/types/Inferences.py +0 -80
- phoenix/server/api/types/InferencesRole.py +0 -23
- phoenix/utilities/json.py +0 -61
- phoenix/utilities/re.py +0 -50
- {arize_phoenix-4.4.4rc5.dist-info → arize_phoenix-4.5.0.dist-info}/licenses/IP_NOTICE +0 -0
- {arize_phoenix-4.4.4rc5.dist-info → arize_phoenix-4.5.0.dist-info}/licenses/LICENSE +0 -0
- /phoenix/server/api/{helpers/__init__.py → helpers.py} +0 -0
phoenix/datasets/types.py
DELETED
|
@@ -1,178 +0,0 @@
|
|
|
1
|
-
from __future__ import annotations
|
|
2
|
-
|
|
3
|
-
from dataclasses import dataclass, field
|
|
4
|
-
from datetime import datetime
|
|
5
|
-
from enum import Enum
|
|
6
|
-
from typing import (
|
|
7
|
-
Any,
|
|
8
|
-
Awaitable,
|
|
9
|
-
Callable,
|
|
10
|
-
Dict,
|
|
11
|
-
List,
|
|
12
|
-
Mapping,
|
|
13
|
-
Optional,
|
|
14
|
-
Sequence,
|
|
15
|
-
Union,
|
|
16
|
-
)
|
|
17
|
-
|
|
18
|
-
from typing_extensions import TypeAlias
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
class AnnotatorKind(Enum):
|
|
22
|
-
CODE = "CODE"
|
|
23
|
-
LLM = "LLM"
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
JSONSerializable: TypeAlias = Optional[Union[Dict[str, Any], List[Any], str, int, float, bool]]
|
|
27
|
-
|
|
28
|
-
ExperimentId: TypeAlias = str
|
|
29
|
-
DatasetId: TypeAlias = str
|
|
30
|
-
DatasetVersionId: TypeAlias = str
|
|
31
|
-
ExampleId: TypeAlias = str
|
|
32
|
-
RepetitionNumber: TypeAlias = int
|
|
33
|
-
ExperimentRunId: TypeAlias = str
|
|
34
|
-
TraceId: TypeAlias = str
|
|
35
|
-
|
|
36
|
-
TaskOutput: TypeAlias = JSONSerializable
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
@dataclass(frozen=True)
|
|
40
|
-
class Example:
|
|
41
|
-
id: ExampleId
|
|
42
|
-
updated_at: datetime
|
|
43
|
-
input: Mapping[str, JSONSerializable]
|
|
44
|
-
output: Mapping[str, JSONSerializable]
|
|
45
|
-
metadata: Mapping[str, JSONSerializable] = field(default_factory=dict)
|
|
46
|
-
|
|
47
|
-
@classmethod
|
|
48
|
-
def from_dict(cls, obj: Mapping[str, Any]) -> Example:
|
|
49
|
-
return cls(
|
|
50
|
-
input=obj["input"],
|
|
51
|
-
output=obj["output"],
|
|
52
|
-
metadata=obj.get("metadata") or {},
|
|
53
|
-
id=obj["id"],
|
|
54
|
-
updated_at=obj["updated_at"],
|
|
55
|
-
)
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
@dataclass(frozen=True)
|
|
59
|
-
class Dataset:
|
|
60
|
-
id: DatasetId
|
|
61
|
-
version_id: DatasetVersionId
|
|
62
|
-
examples: Sequence[Example]
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
@dataclass(frozen=True)
|
|
66
|
-
class TestCase:
|
|
67
|
-
example: Example
|
|
68
|
-
repetition_number: RepetitionNumber
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
@dataclass(frozen=True)
|
|
72
|
-
class Experiment:
|
|
73
|
-
id: ExperimentId
|
|
74
|
-
dataset_id: DatasetId
|
|
75
|
-
dataset_version_id: DatasetVersionId
|
|
76
|
-
project_name: Optional[str] = None
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
@dataclass(frozen=True)
|
|
80
|
-
class ExperimentResult:
|
|
81
|
-
result: TaskOutput
|
|
82
|
-
|
|
83
|
-
@classmethod
|
|
84
|
-
def from_dict(cls, obj: Optional[Mapping[str, Any]]) -> Optional[ExperimentResult]:
|
|
85
|
-
if not obj:
|
|
86
|
-
return None
|
|
87
|
-
return cls(result=obj["result"])
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
@dataclass(frozen=True)
|
|
91
|
-
class ExperimentRun:
|
|
92
|
-
start_time: datetime
|
|
93
|
-
end_time: datetime
|
|
94
|
-
experiment_id: ExperimentId
|
|
95
|
-
dataset_example_id: ExampleId
|
|
96
|
-
repetition_number: RepetitionNumber
|
|
97
|
-
output: Optional[ExperimentResult] = None
|
|
98
|
-
error: Optional[str] = None
|
|
99
|
-
id: Optional[ExperimentRunId] = None
|
|
100
|
-
trace_id: Optional[TraceId] = None
|
|
101
|
-
|
|
102
|
-
@classmethod
|
|
103
|
-
def from_dict(cls, obj: Mapping[str, Any]) -> ExperimentRun:
|
|
104
|
-
return cls(
|
|
105
|
-
start_time=obj["start_time"],
|
|
106
|
-
end_time=obj["end_time"],
|
|
107
|
-
experiment_id=obj["experiment_id"],
|
|
108
|
-
dataset_example_id=obj["dataset_example_id"],
|
|
109
|
-
repetition_number=obj.get("repetition_number") or 1,
|
|
110
|
-
output=ExperimentResult.from_dict(obj["output"]),
|
|
111
|
-
error=obj.get("error"),
|
|
112
|
-
id=obj.get("id"),
|
|
113
|
-
trace_id=obj.get("trace_id"),
|
|
114
|
-
)
|
|
115
|
-
|
|
116
|
-
def __post_init__(self) -> None:
|
|
117
|
-
if bool(self.output) == bool(self.error):
|
|
118
|
-
ValueError("Must specify either result or error")
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
@dataclass(frozen=True)
|
|
122
|
-
class EvaluationResult:
|
|
123
|
-
score: Optional[float] = None
|
|
124
|
-
label: Optional[str] = None
|
|
125
|
-
explanation: Optional[str] = None
|
|
126
|
-
metadata: Mapping[str, JSONSerializable] = field(default_factory=dict)
|
|
127
|
-
|
|
128
|
-
@classmethod
|
|
129
|
-
def from_dict(cls, obj: Optional[Mapping[str, Any]]) -> Optional[EvaluationResult]:
|
|
130
|
-
if not obj:
|
|
131
|
-
return None
|
|
132
|
-
return cls(
|
|
133
|
-
score=obj.get("score"),
|
|
134
|
-
label=obj.get("label"),
|
|
135
|
-
explanation=obj.get("explanation"),
|
|
136
|
-
metadata=obj.get("metadata") or {},
|
|
137
|
-
)
|
|
138
|
-
|
|
139
|
-
def __post_init__(self) -> None:
|
|
140
|
-
if self.score is None and not self.label and not self.explanation:
|
|
141
|
-
ValueError("Must specify one of score, label, or explanation")
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
@dataclass(frozen=True)
|
|
145
|
-
class ExperimentEvaluationRun:
|
|
146
|
-
experiment_run_id: ExperimentRunId
|
|
147
|
-
start_time: datetime
|
|
148
|
-
end_time: datetime
|
|
149
|
-
name: str
|
|
150
|
-
annotator_kind: str
|
|
151
|
-
error: Optional[str] = None
|
|
152
|
-
result: Optional[EvaluationResult] = None
|
|
153
|
-
id: Optional[str] = None
|
|
154
|
-
trace_id: Optional[TraceId] = None
|
|
155
|
-
|
|
156
|
-
@classmethod
|
|
157
|
-
def from_dict(cls, obj: Mapping[str, Any]) -> ExperimentEvaluationRun:
|
|
158
|
-
return cls(
|
|
159
|
-
experiment_run_id=obj["experiment_run_id"],
|
|
160
|
-
start_time=obj["start_time"],
|
|
161
|
-
end_time=obj["end_time"],
|
|
162
|
-
name=obj["name"],
|
|
163
|
-
annotator_kind=obj["annotator_kind"],
|
|
164
|
-
error=obj.get("error"),
|
|
165
|
-
result=EvaluationResult.from_dict(obj.get("result")),
|
|
166
|
-
id=obj.get("id"),
|
|
167
|
-
trace_id=obj.get("trace_id"),
|
|
168
|
-
)
|
|
169
|
-
|
|
170
|
-
def __post_init__(self) -> None:
|
|
171
|
-
if bool(self.result) == bool(self.error):
|
|
172
|
-
ValueError("Must specify either result or error")
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
ExperimentTask: TypeAlias = Union[
|
|
176
|
-
Callable[[Example], TaskOutput],
|
|
177
|
-
Callable[[Example], Awaitable[TaskOutput]],
|
|
178
|
-
]
|
phoenix/db/insertion/dataset.py
DELETED
|
@@ -1,237 +0,0 @@
|
|
|
1
|
-
import logging
|
|
2
|
-
from dataclasses import dataclass, field
|
|
3
|
-
from datetime import datetime, timezone
|
|
4
|
-
from enum import Enum
|
|
5
|
-
from itertools import chain
|
|
6
|
-
from typing import (
|
|
7
|
-
Any,
|
|
8
|
-
Awaitable,
|
|
9
|
-
Dict,
|
|
10
|
-
FrozenSet,
|
|
11
|
-
Iterable,
|
|
12
|
-
Iterator,
|
|
13
|
-
Mapping,
|
|
14
|
-
Optional,
|
|
15
|
-
Union,
|
|
16
|
-
cast,
|
|
17
|
-
)
|
|
18
|
-
|
|
19
|
-
from sqlalchemy import insert, select
|
|
20
|
-
from sqlalchemy.ext.asyncio import AsyncSession
|
|
21
|
-
from typing_extensions import TypeAlias
|
|
22
|
-
|
|
23
|
-
from phoenix.db import models
|
|
24
|
-
from phoenix.db.insertion.helpers import DataManipulationEvent
|
|
25
|
-
|
|
26
|
-
logger = logging.getLogger(__name__)
|
|
27
|
-
|
|
28
|
-
DatasetId: TypeAlias = int
|
|
29
|
-
DatasetVersionId: TypeAlias = int
|
|
30
|
-
DatasetExampleId: TypeAlias = int
|
|
31
|
-
DatasetExampleRevisionId: TypeAlias = int
|
|
32
|
-
SpanRowId: TypeAlias = int
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
@dataclass(frozen=True)
|
|
36
|
-
class ExampleContent:
|
|
37
|
-
input: Dict[str, Any] = field(default_factory=dict)
|
|
38
|
-
output: Dict[str, Any] = field(default_factory=dict)
|
|
39
|
-
metadata: Dict[str, Any] = field(default_factory=dict)
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
Examples: TypeAlias = Iterable[ExampleContent]
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
@dataclass(frozen=True)
|
|
46
|
-
class DatasetExampleAdditionEvent(DataManipulationEvent):
|
|
47
|
-
dataset_id: DatasetId
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
async def insert_dataset(
|
|
51
|
-
session: AsyncSession,
|
|
52
|
-
name: str,
|
|
53
|
-
description: Optional[str] = None,
|
|
54
|
-
metadata: Optional[Mapping[str, Any]] = None,
|
|
55
|
-
created_at: Optional[datetime] = None,
|
|
56
|
-
) -> DatasetId:
|
|
57
|
-
id_ = await session.scalar(
|
|
58
|
-
insert(models.Dataset)
|
|
59
|
-
.values(
|
|
60
|
-
name=name,
|
|
61
|
-
description=description,
|
|
62
|
-
metadata_=metadata,
|
|
63
|
-
created_at=created_at,
|
|
64
|
-
)
|
|
65
|
-
.returning(models.Dataset.id)
|
|
66
|
-
)
|
|
67
|
-
return cast(DatasetId, id_)
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
async def insert_dataset_version(
|
|
71
|
-
session: AsyncSession,
|
|
72
|
-
dataset_id: DatasetId,
|
|
73
|
-
description: Optional[str] = None,
|
|
74
|
-
metadata: Optional[Mapping[str, Any]] = None,
|
|
75
|
-
created_at: Optional[datetime] = None,
|
|
76
|
-
) -> DatasetVersionId:
|
|
77
|
-
id_ = await session.scalar(
|
|
78
|
-
insert(models.DatasetVersion)
|
|
79
|
-
.values(
|
|
80
|
-
dataset_id=dataset_id,
|
|
81
|
-
description=description,
|
|
82
|
-
metadata_=metadata,
|
|
83
|
-
created_at=created_at,
|
|
84
|
-
)
|
|
85
|
-
.returning(models.DatasetVersion.id)
|
|
86
|
-
)
|
|
87
|
-
return cast(DatasetVersionId, id_)
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
async def insert_dataset_example(
|
|
91
|
-
session: AsyncSession,
|
|
92
|
-
dataset_id: DatasetId,
|
|
93
|
-
span_rowid: Optional[SpanRowId] = None,
|
|
94
|
-
created_at: Optional[datetime] = None,
|
|
95
|
-
) -> DatasetExampleId:
|
|
96
|
-
id_ = await session.scalar(
|
|
97
|
-
insert(models.DatasetExample)
|
|
98
|
-
.values(
|
|
99
|
-
dataset_id=dataset_id,
|
|
100
|
-
span_rowid=span_rowid,
|
|
101
|
-
created_at=created_at,
|
|
102
|
-
)
|
|
103
|
-
.returning(models.DatasetExample.id)
|
|
104
|
-
)
|
|
105
|
-
return cast(DatasetExampleId, id_)
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
class RevisionKind(Enum):
|
|
109
|
-
CREATE = "CREATE"
|
|
110
|
-
PATCH = "PATCH"
|
|
111
|
-
DELETE = "DELETE"
|
|
112
|
-
|
|
113
|
-
@classmethod
|
|
114
|
-
def _missing_(cls, v: Any) -> "RevisionKind":
|
|
115
|
-
if isinstance(v, str) and v and v.isascii() and not v.isupper():
|
|
116
|
-
return cls(v.upper())
|
|
117
|
-
raise ValueError(f"Invalid revision kind: {v}")
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
async def insert_dataset_example_revision(
|
|
121
|
-
session: AsyncSession,
|
|
122
|
-
dataset_version_id: DatasetVersionId,
|
|
123
|
-
dataset_example_id: DatasetExampleId,
|
|
124
|
-
input: Mapping[str, Any],
|
|
125
|
-
output: Mapping[str, Any],
|
|
126
|
-
metadata: Optional[Mapping[str, Any]] = None,
|
|
127
|
-
revision_kind: RevisionKind = RevisionKind.CREATE,
|
|
128
|
-
created_at: Optional[datetime] = None,
|
|
129
|
-
) -> DatasetExampleRevisionId:
|
|
130
|
-
id_ = await session.scalar(
|
|
131
|
-
insert(models.DatasetExampleRevision)
|
|
132
|
-
.values(
|
|
133
|
-
dataset_version_id=dataset_version_id,
|
|
134
|
-
dataset_example_id=dataset_example_id,
|
|
135
|
-
input=input,
|
|
136
|
-
output=output,
|
|
137
|
-
metadata_=metadata,
|
|
138
|
-
revision_kind=revision_kind.value,
|
|
139
|
-
created_at=created_at,
|
|
140
|
-
)
|
|
141
|
-
.returning(models.DatasetExampleRevision.id)
|
|
142
|
-
)
|
|
143
|
-
return cast(DatasetExampleRevisionId, id_)
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
class DatasetAction(Enum):
|
|
147
|
-
CREATE = "create"
|
|
148
|
-
APPEND = "append"
|
|
149
|
-
|
|
150
|
-
@classmethod
|
|
151
|
-
def _missing_(cls, v: Any) -> "DatasetAction":
|
|
152
|
-
if isinstance(v, str) and v and v.isascii() and not v.islower():
|
|
153
|
-
return cls(v.lower())
|
|
154
|
-
raise ValueError(f"Invalid dateset action: {v}")
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
async def add_dataset_examples(
|
|
158
|
-
session: AsyncSession,
|
|
159
|
-
name: str,
|
|
160
|
-
examples: Union[Examples, Awaitable[Examples]],
|
|
161
|
-
description: Optional[str] = None,
|
|
162
|
-
metadata: Optional[Mapping[str, Any]] = None,
|
|
163
|
-
action: DatasetAction = DatasetAction.CREATE,
|
|
164
|
-
) -> Optional[DatasetExampleAdditionEvent]:
|
|
165
|
-
created_at = datetime.now(timezone.utc)
|
|
166
|
-
dataset_id: Optional[DatasetId] = None
|
|
167
|
-
if action is DatasetAction.APPEND and name:
|
|
168
|
-
dataset_id = await session.scalar(
|
|
169
|
-
select(models.Dataset.id).where(models.Dataset.name == name)
|
|
170
|
-
)
|
|
171
|
-
if action is DatasetAction.CREATE or dataset_id is None:
|
|
172
|
-
try:
|
|
173
|
-
dataset_id = await insert_dataset(
|
|
174
|
-
session=session,
|
|
175
|
-
name=name,
|
|
176
|
-
description=description,
|
|
177
|
-
metadata=metadata,
|
|
178
|
-
created_at=created_at,
|
|
179
|
-
)
|
|
180
|
-
except Exception:
|
|
181
|
-
logger.exception(f"Failed to insert dataset: {name=}")
|
|
182
|
-
raise
|
|
183
|
-
try:
|
|
184
|
-
dataset_version_id = await insert_dataset_version(
|
|
185
|
-
session=session,
|
|
186
|
-
dataset_id=dataset_id,
|
|
187
|
-
created_at=created_at,
|
|
188
|
-
)
|
|
189
|
-
except Exception:
|
|
190
|
-
logger.exception(f"Failed to insert dataset version for {dataset_id=}")
|
|
191
|
-
raise
|
|
192
|
-
for example in (await examples) if isinstance(examples, Awaitable) else examples:
|
|
193
|
-
try:
|
|
194
|
-
dataset_example_id = await insert_dataset_example(
|
|
195
|
-
session=session,
|
|
196
|
-
dataset_id=dataset_id,
|
|
197
|
-
created_at=created_at,
|
|
198
|
-
)
|
|
199
|
-
except Exception:
|
|
200
|
-
logger.exception(f"Failed to insert dataset example for {dataset_id=}")
|
|
201
|
-
raise
|
|
202
|
-
try:
|
|
203
|
-
await insert_dataset_example_revision(
|
|
204
|
-
session=session,
|
|
205
|
-
dataset_version_id=dataset_version_id,
|
|
206
|
-
dataset_example_id=dataset_example_id,
|
|
207
|
-
input=example.input,
|
|
208
|
-
output=example.output,
|
|
209
|
-
metadata=example.metadata,
|
|
210
|
-
created_at=created_at,
|
|
211
|
-
)
|
|
212
|
-
except Exception:
|
|
213
|
-
logger.exception(
|
|
214
|
-
f"Failed to insert dataset example revision for {dataset_version_id=}, "
|
|
215
|
-
f"{dataset_example_id=}"
|
|
216
|
-
)
|
|
217
|
-
raise
|
|
218
|
-
return DatasetExampleAdditionEvent(dataset_id=dataset_id)
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
@dataclass(frozen=True)
|
|
222
|
-
class DatasetKeys:
|
|
223
|
-
input: FrozenSet[str]
|
|
224
|
-
output: FrozenSet[str]
|
|
225
|
-
metadata: FrozenSet[str]
|
|
226
|
-
|
|
227
|
-
def __iter__(self) -> Iterator[str]:
|
|
228
|
-
yield from sorted(set(chain(self.input, self.output, self.metadata)))
|
|
229
|
-
|
|
230
|
-
def check_differences(self, column_headers_set: FrozenSet[str]) -> None:
|
|
231
|
-
for category, keys in (
|
|
232
|
-
("input", self.input),
|
|
233
|
-
("output", self.output),
|
|
234
|
-
("metadata", self.metadata),
|
|
235
|
-
):
|
|
236
|
-
if diff := keys.difference(column_headers_set):
|
|
237
|
-
raise ValueError(f"{category} keys not found in table column headers: {diff}")
|
phoenix/db/migrations/types.py
DELETED
|
@@ -1,29 +0,0 @@
|
|
|
1
|
-
from typing import Any
|
|
2
|
-
|
|
3
|
-
from sqlalchemy import JSON
|
|
4
|
-
from sqlalchemy.dialects import postgresql
|
|
5
|
-
from sqlalchemy.ext.compiler import compiles
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
class JSONB(JSON):
|
|
9
|
-
# See https://docs.sqlalchemy.org/en/20/core/custom_types.html
|
|
10
|
-
__visit_name__ = "JSONB"
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
@compiles(JSONB, "sqlite") # type: ignore
|
|
14
|
-
def _(*args: Any, **kwargs: Any) -> str:
|
|
15
|
-
# See https://docs.sqlalchemy.org/en/20/core/custom_types.html
|
|
16
|
-
return "JSONB"
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
JSON_ = (
|
|
20
|
-
JSON()
|
|
21
|
-
.with_variant(
|
|
22
|
-
postgresql.JSONB(), # type: ignore
|
|
23
|
-
"postgresql",
|
|
24
|
-
)
|
|
25
|
-
.with_variant(
|
|
26
|
-
JSONB(),
|
|
27
|
-
"sqlite",
|
|
28
|
-
)
|
|
29
|
-
)
|