Skip to content

Commit f2a4c29

Browse files
authored
Merge pull request #774 from parea-ai/PAI-1048-public-api-get-trace-logs-of-experiment
feat: fetch logs for experiment
2 parents a506f52 + 71ca6e2 commit f2a4c29

File tree

5 files changed

+61
-5
lines changed

5 files changed

+61
-5
lines changed

parea/client.py

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
from parea.cache.cache import Cache
1515
from parea.constants import PAREA_OS_ENV_EXPERIMENT_UUID
1616
from parea.experiment.datasets import create_test_cases, create_test_collection
17-
from parea.helpers import gen_trace_id, serialize_metadata_values, structure_trace_log_from_api
17+
from parea.helpers import gen_trace_id, serialize_metadata_values, structure_trace_log_from_api, structure_trace_logs_from_api
1818
from parea.parea_logger import parea_logger
1919
from parea.schemas.models import (
2020
Completion,
@@ -31,6 +31,7 @@
3131
ProjectSchema,
3232
TestCaseCollection,
3333
TraceLog,
34+
TraceLogFilters,
3435
UseDeployedPrompt,
3536
UseDeployedPromptResponse,
3637
)
@@ -52,6 +53,7 @@
5253
ADD_TEST_CASES_ENDPOINT = "/testcases"
5354
GET_TRACE_LOG_ENDPOINT = "/trace_log/{trace_id}"
5455
LIST_EXPERIMENTS_ENDPOINT = "/experiments"
56+
GET_EXPERIMENT_LOGS_ENDPOINT = "/experiment/{experiment_uuid}/trace_logs"
5557

5658

5759
@define
@@ -356,6 +358,14 @@ async def alist_experiment_uuids(self, filter_conditions: Optional[ListExperimen
356358
response = await self._client.request_async("POST", LIST_EXPERIMENTS_ENDPOINT, data=asdict(filter_conditions))
357359
return response.json()
358360

361+
def get_experiment_trace_logs(self, experiment_uuid: str, filters: TraceLogFilters = TraceLogFilters()) -> List[TraceLog]:
362+
response = self._client.request("POST", GET_EXPERIMENT_LOGS_ENDPOINT.format(experiment_uuid=experiment_uuid), data=asdict(filters))
363+
return structure_trace_logs_from_api(response.json())
364+
365+
async def aget_experiment_trace_logs(self, experiment_uuid: str, filters: TraceLogFilters = TraceLogFilters()) -> List[TraceLog]:
366+
response = await self._client.request_async("POST", GET_EXPERIMENT_LOGS_ENDPOINT.format(experiment_uuid=experiment_uuid), data=asdict(filters))
367+
return structure_trace_logs_from_api(response.json())
368+
359369

360370
_initialized_parea_wrapper = False
361371

parea/cookbook/list_experiments.py

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99

1010
p = Parea(api_key=os.getenv("PAREA_API_KEY"))
1111

12-
exp_uuids = p.list_experiment_uuids(ListExperimentUUIDsFilters())
13-
print(len(exp_uuids))
14-
print(exp_uuids)
12+
exp_uuids = p.list_experiment_uuids(ListExperimentUUIDsFilters(experiment_name_filter="Greeting"))
13+
print(f"Num. experiments: {len(exp_uuids)}")
14+
trace_logs = p.get_experiment_trace_logs(exp_uuids[0])
15+
print(f"Num. trace logs: {len(trace_logs)}")

parea/helpers.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,3 +93,7 @@ def structure_union_type(obj: Any, cl: type) -> Any:
9393
converter = GenConverter()
9494
converter.register_structure_hook(Union[str, Dict[str, str], None], structure_union_type)
9595
return converter.structure(d, TraceLog)
96+
97+
98+
def structure_trace_logs_from_api(data: List[dict]) -> List[TraceLog]:
99+
return [structure_trace_log_from_api(d) for d in data]

parea/schemas/models.py

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,23 @@ class TraceLogImage:
8888
caption: Optional[str] = None
8989

9090

91+
@define
92+
class TraceLogCommentSchema:
93+
comment: str
94+
user_id: str
95+
created_at: str
96+
97+
98+
@define
99+
class TraceLogAnnotationSchema:
100+
created_at: str
101+
user_id: str
102+
score: float
103+
user_email_address: Optional[str] = None
104+
annotation_name: Optional[str] = None
105+
value: Optional[str] = None
106+
107+
91108
@define
92109
class TraceLog(EvaluatedLog):
93110
trace_id: Optional[str] = field(default=None, validator=validators.instance_of(str))
@@ -120,6 +137,10 @@ class TraceLog(EvaluatedLog):
120137
experiment_uuid: Optional[str] = None
121138
images: Optional[List[TraceLogImage]] = field(factory=list)
122139

140+
# from UI
141+
comments: Optional[List[TraceLogCommentSchema]] = None
142+
annotations: Optional[dict[int, dict[str, TraceLogAnnotationSchema]]] = None
143+
123144

124145
@define
125146
class TraceLogTree(TraceLog):
@@ -286,3 +307,23 @@ class ListExperimentUUIDsFilters:
286307
metadata_filter: Optional[Dict[str, Any]] = None
287308
experiment_name_filter: Optional[str] = None
288309
run_name_filter: Optional[str] = None
310+
311+
312+
class FilterOperator(str, Enum):
313+
EQUALS = "equals"
314+
NOT_EQUALS = "not_equals"
315+
LIKE = "like"
316+
GREATER_THAN_OR_EQUAL = "greater_than_or_equal"
317+
LESS_THAN_OR_EQUAL = "less_than_or_equal"
318+
GRATER_THAN = "greater_than"
319+
LESS_THAN = "less_than"
320+
IS_NULL = "is_null"
321+
EXISTS = "exists"
322+
IN = "in"
323+
324+
325+
@define
326+
class TraceLogFilters:
327+
filter_field: Optional[str] = None
328+
filter_operator: Optional[FilterOperator] = None
329+
filter_value: Optional[str] = None

pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ build-backend = "poetry.core.masonry.api"
66
[tool.poetry]
77
name = "parea-ai"
88
packages = [{ include = "parea" }]
9-
version = "0.2.133"
9+
version = "0.2.134"
1010
description = "Parea python sdk"
1111
readme = "README.md"
1212
authors = ["joel-parea-ai <[email protected]>"]

0 commit comments

Comments
 (0)