Skip to content

Commit e529f7f

Browse files
committed
updated adapters
1 parent 74cca5d commit e529f7f

File tree

4 files changed

+125
-189
lines changed

4 files changed

+125
-189
lines changed

eval_protocol/adapters/__init__.py

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,3 +99,19 @@
9999
__all__.extend(["WeaveAdapter"])
100100
except ImportError:
101101
pass
102+
103+
# DataFrame adapter (pandas integration for Lilac, etc.)
104+
try:
105+
from .dataframe import (
106+
evaluation_rows_to_dataframe,
107+
dataframe_to_evaluation_rows,
108+
)
109+
110+
__all__.extend(
111+
[
112+
"evaluation_rows_to_dataframe",
113+
"dataframe_to_evaluation_rows",
114+
]
115+
)
116+
except ImportError:
117+
pass
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
"""
2+
Pandas DataFrame adapter for Eval Protocol.
3+
4+
This module provides utilities for converting between EvaluationRow format
5+
and pandas DataFrame format, enabling integration with data curation tools
6+
such as Lilac, Great Expectations, or any pandas-based workflow.
7+
8+
Example usage:
9+
>>> from eval_protocol.adapters.dataframe import (
10+
... evaluation_rows_to_dataframe,
11+
... dataframe_to_evaluation_rows,
12+
... )
13+
>>>
14+
>>> # Convert EvaluationRows to DataFrame
15+
>>> df = evaluation_rows_to_dataframe(rows)
16+
>>>
17+
>>> # Convert back to EvaluationRows
18+
>>> rows = dataframe_to_evaluation_rows(df)
19+
"""
20+
21+
from __future__ import annotations
22+
23+
import logging
24+
25+
import pandas as pd
26+
27+
from ..models import EvaluationRow
28+
29+
logger = logging.getLogger(__name__)
30+
31+
32+
def evaluation_rows_to_dataframe(rows: list[EvaluationRow]) -> pd.DataFrame:
33+
"""Convert EvaluationRows to a pandas DataFrame.
34+
35+
Uses EvaluationRow.to_dict() for serialization.
36+
37+
Args:
38+
rows: List of EvaluationRow objects
39+
40+
Returns:
41+
DataFrame with 'data_json' containing serialized rows plus convenience fields
42+
"""
43+
records = [row.to_dict() for row in rows]
44+
return pd.DataFrame(records)
45+
46+
47+
def dataframe_to_evaluation_rows(df: pd.DataFrame) -> list[EvaluationRow]:
48+
"""Convert a pandas DataFrame back to EvaluationRows.
49+
50+
Uses EvaluationRow.from_dict() for deserialization.
51+
52+
Args:
53+
df: DataFrame with 'data_json' column containing serialized EvaluationRows
54+
55+
Returns:
56+
List of EvaluationRow objects
57+
"""
58+
rows = []
59+
for _, row_data in df.iterrows():
60+
try:
61+
row = EvaluationRow.from_dict(row_data.to_dict())
62+
rows.append(row)
63+
except Exception as e:
64+
logger.warning(f"Failed to convert row: {e}")
65+
continue
66+
return rows

eval_protocol/adapters/lilac.py

Lines changed: 0 additions & 189 deletions
This file was deleted.

eval_protocol/models.py

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -953,6 +953,49 @@ def get_termination_reason(self) -> str:
953953
return str(reason)
954954
return "unknown"
955955

956+
def to_dict(self) -> Dict[str, Any]:
957+
"""Serialize this EvaluationRow to a dictionary.
958+
959+
The entire EvaluationRow is serialized to JSON, allowing full reconstruction.
960+
Additional scalar fields are included for convenient filtering/grouping.
961+
962+
Returns:
963+
Dictionary with 'data_json' containing the full serialized row,
964+
plus convenience fields for filtering.
965+
"""
966+
return {
967+
"data_json": self.model_dump_json(),
968+
"row_id": self.input_metadata.row_id if self.input_metadata else None,
969+
"score": self.evaluation_result.score if self.evaluation_result else None,
970+
"message_count": len(self.messages),
971+
"has_tools": bool(self.tools),
972+
"created_at": self.created_at.isoformat() if self.created_at else None,
973+
}
974+
975+
@classmethod
976+
def from_dict(cls, data: Dict[str, Any]) -> "EvaluationRow":
977+
"""Reconstruct an EvaluationRow from a dictionary.
978+
979+
Args:
980+
data: Dictionary containing 'data_json' with the serialized EvaluationRow.
981+
982+
Returns:
983+
Reconstructed EvaluationRow instance.
984+
985+
Raises:
986+
ValueError: If 'data_json' is missing or invalid.
987+
"""
988+
from pydantic import ValidationError
989+
990+
data_json = data.get("data_json")
991+
if not data_json:
992+
raise ValueError("Missing 'data_json' field in dictionary")
993+
994+
try:
995+
return cls.model_validate_json(data_json)
996+
except ValidationError as e:
997+
raise ValueError(f"Failed to deserialize EvaluationRow: {e}") from e
998+
956999
def __hash__(self) -> int:
9571000
# Use a stable hash that works across Python processes
9581001
return self._stable_hash()

0 commit comments

Comments
 (0)