Skip to content

Commit 2573496

Browse files
committed
fix(run-experiment): pass version param only if it's present
1 parent 16bccdb commit 2573496

2 files changed

Lines changed: 95 additions & 9 deletions

File tree

langfuse/_client/client.py

Lines changed: 23 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2921,17 +2921,31 @@ async def _process_experiment_item(
29212921
try:
29222922
# Use sync API to avoid event loop issues when run_async_safely
29232923
# creates multiple event loops across different threads
2924+
2925+
# Create request, only include datasetVersion if not None
2926+
if dataset_version is not None:
2927+
dataset_run_item_request = CreateDatasetRunItemRequest(
2928+
run_name=experiment_run_name,
2929+
run_description=experiment_description,
2930+
metadata=experiment_metadata,
2931+
dataset_item_id=item.id, # type: ignore
2932+
trace_id=trace_id,
2933+
observation_id=span.id,
2934+
dataset_version=dataset_version,
2935+
)
2936+
else:
2937+
dataset_run_item_request = CreateDatasetRunItemRequest(
2938+
run_name=experiment_run_name,
2939+
run_description=experiment_description,
2940+
metadata=experiment_metadata,
2941+
dataset_item_id=item.id, # type: ignore
2942+
trace_id=trace_id,
2943+
observation_id=span.id,
2944+
)
2945+
29242946
dataset_run_item = await asyncio.to_thread(
29252947
self.api.dataset_run_items.create,
2926-
request=CreateDatasetRunItemRequest(
2927-
runName=experiment_run_name,
2928-
runDescription=experiment_description,
2929-
metadata=experiment_metadata,
2930-
datasetItemId=item.id, # type: ignore
2931-
traceId=trace_id,
2932-
observationId=span.id,
2933-
datasetVersion=dataset_version,
2934-
),
2948+
request=dataset_run_item_request,
29352949
)
29362950

29372951
dataset_run_id = dataset_run_item.dataset_run_id

tests/test_datasets.py

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -640,3 +640,75 @@ def simple_task(*, item, **kwargs):
640640
assert result.name == "Versioned Dataset Test"
641641
assert len(result.item_results) == 1 # Only one item in versioned dataset
642642
assert result.item_results[0].output == 4
643+
644+
645+
def test_run_experiment_without_dataset_version(monkeypatch):
646+
langfuse = Langfuse(debug=False)
647+
648+
# Create dataset
649+
name = create_uuid()
650+
langfuse.create_dataset(name=name)
651+
652+
# Create item
653+
langfuse.create_dataset_item(
654+
dataset_name=name, input={"question": "What is 2+2?"}, expected_output=4
655+
)
656+
langfuse.flush()
657+
time.sleep(3)
658+
659+
# Get dataset without version timestamp - this should have version=None
660+
dataset = langfuse.get_dataset(name)
661+
assert dataset.version is None, "Dataset should have no version"
662+
663+
# Capture HTTP requests to dataset-run-items endpoint to inspect the request body
664+
captured_requests = []
665+
original_request = langfuse.api._client_wrapper.httpx_client.request
666+
667+
def capture_request(method, url, **kwargs):
668+
# Capture requests to the dataset-run-items endpoint
669+
if "dataset-run-items" in str(url) and method.upper() == "POST":
670+
# Capture the JSON body being sent
671+
captured_requests.append(kwargs.get("json"))
672+
return original_request(method, url, **kwargs)
673+
674+
monkeypatch.setattr(
675+
langfuse.api._client_wrapper.httpx_client, "request", capture_request
676+
)
677+
678+
# Run a simple experiment on the dataset
679+
def simple_task(*, item, **kwargs):
680+
# Just return a static answer
681+
return item.expected_output
682+
683+
result = dataset.run_experiment(
684+
name="Dataset without version Test",
685+
description="Testing experiment with dataset without version",
686+
task=simple_task,
687+
)
688+
689+
# Verify experiment ran successfully
690+
assert result.name == "Dataset without version Test"
691+
assert len(result.item_results) == 1 # Only one item in dataset
692+
assert result.item_results[0].output == 4
693+
assert result.dataset_run_id is not None, "Should have created a dataset run"
694+
695+
# Verify that HTTP requests were captured
696+
assert len(captured_requests) > 0, (
697+
"Should have captured dataset run item creation requests"
698+
)
699+
700+
# Verify that datasetVersion was NOT included in any request body
701+
for request_body in captured_requests:
702+
assert request_body is not None, "Request body should not be None"
703+
# Check if request_body is a dict or has a dict method
704+
if hasattr(request_body, "dict"):
705+
body_dict = request_body.dict()
706+
elif isinstance(request_body, dict):
707+
body_dict = request_body
708+
else:
709+
body_dict = json.loads(json.dumps(request_body))
710+
711+
assert "datasetVersion" not in body_dict, (
712+
f"datasetVersion should not be in request body when dataset has no version. "
713+
f"Found in body: {body_dict}"
714+
)

0 commit comments

Comments
 (0)