Skip to content

Commit 86773b9

Browse files
committed
made MetricResult json serialisable for pydantic
1 parent 0ca9088 commit 86773b9

File tree

3 files changed

+63
-13
lines changed

3 files changed

+63
-13
lines changed

nbs/metric/result.ipynb

Lines changed: 33 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -291,6 +291,18 @@
291291
" return value\n",
292292
" return MetricResult(result=value)\n",
293293
"\n",
294+
"@patch\n",
295+
"def __json__(self: MetricResult):\n",
296+
" \"\"\"Return data for JSON serialization.\n",
297+
" \n",
298+
" This method is used by json.dumps and other JSON serializers \n",
299+
" to convert MetricResult to a JSON-compatible format.\n",
300+
" \"\"\"\n",
301+
" return {\n",
302+
" \"result\": self._result,\n",
303+
" \"reason\": self.reason,\n",
304+
" }\n",
305+
"\n",
294306
"# Add Pydantic compatibility methods\n",
295307
"@patch(cls_method=True)\n",
296308
"def __get_pydantic_core_schema__(\n",
@@ -299,7 +311,22 @@
299311
" _handler: GetCoreSchemaHandler\n",
300312
") -> core_schema.CoreSchema:\n",
301313
" \"\"\"Generate a Pydantic core schema for MetricResult.\"\"\"\n",
302-
" return core_schema.with_info_plain_validator_function(cls.validate)\n",
314+
" # Create a schema that handles both validation and serialization\n",
315+
" return core_schema.union_schema([\n",
316+
" # First schema: handles validation of MetricResult instances\n",
317+
" core_schema.is_instance_schema(MetricResult),\n",
318+
" \n",
319+
" # Second schema: handles validation of other values and conversion to MetricResult\n",
320+
" core_schema.chain_schema([\n",
321+
" core_schema.any_schema(),\n",
322+
" core_schema.no_info_plain_validator_function(\n",
323+
" lambda value: MetricResult(result=value) if not isinstance(value, MetricResult) else value\n",
324+
" ),\n",
325+
" ]),\n",
326+
" ], serialization=core_schema.plain_serializer_function_ser_schema(\n",
327+
" # This function handles serialization\n",
328+
" lambda instance: instance.__json__()\n",
329+
" ))\n",
303330
"\n",
304331
"\n",
305332
"@patch\n",
@@ -369,13 +396,13 @@
369396
{
370397
"cell_type": "code",
371398
"execution_count": null,
372-
"id": "9d32b10f",
399+
"id": "27f9bc1c",
373400
"metadata": {},
374401
"outputs": [
375402
{
376403
"data": {
377404
"text/plain": [
378-
"'test'"
405+
"'{\"response\":\"test\",\"grade\":{\"result\":1,\"reason\":\"test\"},\"faithfulness\":{\"result\":1,\"reason\":\"test\"}}'"
379406
]
380407
},
381408
"execution_count": null,
@@ -384,16 +411,10 @@
384411
}
385412
],
386413
"source": [
387-
"m.model_dump()[\"faithfulness\"].reason"
414+
"mt = TestModel(response=\"test\", grade=MetricResult(result=1, reason=\"test\"), faithfulness=MetricResult(result=1, reason=\"test\"))\n",
415+
"\n",
416+
"mt.model_dump_json()"
388417
]
389-
},
390-
{
391-
"cell_type": "code",
392-
"execution_count": null,
393-
"id": "bde70d56",
394-
"metadata": {},
395-
"outputs": [],
396-
"source": []
397418
}
398419
],
399420
"metadata": {

ragas_experimental/_modidx.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -349,6 +349,8 @@
349349
'ragas_experimental/metric/result.py'),
350350
'ragas_experimental.metric.result.MetricResult.__iter__': ( 'metric/result.html#metricresult.__iter__',
351351
'ragas_experimental/metric/result.py'),
352+
'ragas_experimental.metric.result.MetricResult.__json__': ( 'metric/result.html#metricresult.__json__',
353+
'ragas_experimental/metric/result.py'),
352354
'ragas_experimental.metric.result.MetricResult.__le__': ( 'metric/result.html#metricresult.__le__',
353355
'ragas_experimental/metric/result.py'),
354356
'ragas_experimental.metric.result.MetricResult.__len__': ( 'metric/result.html#metricresult.__len__',

ragas_experimental/metric/result.py

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -188,6 +188,18 @@ def validate(cls: MetricResult, value: t.Any, info: ValidationInfo):
188188
return value
189189
return MetricResult(result=value)
190190

191+
@patch
192+
def __json__(self: MetricResult):
193+
"""Return data for JSON serialization.
194+
195+
This method is used by json.dumps and other JSON serializers
196+
to convert MetricResult to a JSON-compatible format.
197+
"""
198+
return {
199+
"result": self._result,
200+
"reason": self.reason,
201+
}
202+
191203
# Add Pydantic compatibility methods
192204
@patch(cls_method=True)
193205
def __get_pydantic_core_schema__(
@@ -196,7 +208,22 @@ def __get_pydantic_core_schema__(
196208
_handler: GetCoreSchemaHandler
197209
) -> core_schema.CoreSchema:
198210
"""Generate a Pydantic core schema for MetricResult."""
199-
return core_schema.with_info_plain_validator_function(cls.validate)
211+
# Create a schema that handles both validation and serialization
212+
return core_schema.union_schema([
213+
# First schema: handles validation of MetricResult instances
214+
core_schema.is_instance_schema(MetricResult),
215+
216+
# Second schema: handles validation of other values and conversion to MetricResult
217+
core_schema.chain_schema([
218+
core_schema.any_schema(),
219+
core_schema.no_info_plain_validator_function(
220+
lambda value: MetricResult(result=value) if not isinstance(value, MetricResult) else value
221+
),
222+
]),
223+
], serialization=core_schema.plain_serializer_function_ser_schema(
224+
# This function handles serialization
225+
lambda instance: instance.__json__()
226+
))
200227

201228

202229
@patch

0 commit comments

Comments
 (0)