Skip to content

Commit

Permalink
python[patch]: fix pytest integration example syncing (#1450)
Browse files Browse the repository at this point in the history
- properly lock access updating shared resource
- correctly pull modified_at when updating example
  • Loading branch information
baskaryan authored Jan 22, 2025
1 parent 95fe3b5 commit 8ce0bbf
Show file tree
Hide file tree
Showing 3 changed files with 13 additions and 15 deletions.
2 changes: 1 addition & 1 deletion python/langsmith/pytest_plugin.py
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ def pytest_report_teststatus(report, config):
# The hook normally returns a 3-tuple: (short_letter, verbose_word, color)
# By returning empty strings, the progress characters won't show.
if config.getoption("--output") in ("langsmith", "ls"):
return "", "", None
return "", "", ""


class LangSmithPlugin:
Expand Down
24 changes: 11 additions & 13 deletions python/langsmith/testing/_internal.py
Original file line number Diff line number Diff line change
Expand Up @@ -550,7 +550,7 @@ def get_version(
if not example_id:
return self._version
else:
return self._example_modified_at[example_id]
return self._example_modified_at.get(example_id)

def submit_result(
self,
Expand Down Expand Up @@ -620,26 +620,23 @@ def _sync_example(
metadata=metadata,
created_at=self._experiment.start_time,
)
modified_at = example.modified_at
else:
if (
(inputs is not None and inputs != example.inputs)
or (outputs is not None and outputs != example.outputs)
or (metadata is not None and metadata != example.metadata)
or str(example.dataset_id) != str(self.id)
):
response = self.client.update_example(
self.client.update_example(
example_id=example.id,
inputs=inputs,
outputs=outputs,
metadata=metadata,
dataset_id=self.id,
)
modified_at = datetime.datetime.fromisoformat(response["modified_at"])
else:
modified_at = example.modified_at
if modified_at:
self.update_version(modified_at, example_id=example_id)
example = self.client.read_example(example_id=example.id)
if example.modified_at:
self.update_version(example.modified_at, example_id=example_id)

def _submit_feedback(
self,
Expand Down Expand Up @@ -668,8 +665,9 @@ def shutdown(self):

def wait_example_updates(self, example_id: ID_TYPE):
"""Wait for all example updates to complete."""
while self._example_futures[example_id]:
self._example_futures[example_id].pop().result()
with self._lock:
while self._example_futures[example_id]:
self._example_futures[example_id].pop().result()

def end_run(
self,
Expand Down Expand Up @@ -697,7 +695,7 @@ def _end_run(
# Ensure example is fully updated
self.wait_example_updates(example_id)
# Ensure that run end time is after example modified at.
example_modified_at = self.get_version(example_id=example_id)
example_modified_at = self.get_version(example_id=example_id) or end_time
end_time = max(example_modified_at, end_time)
run_tree.end(outputs=outputs, end_time=end_time)
run_tree.patch()
Expand Down Expand Up @@ -778,11 +776,11 @@ def end_time(self) -> None:
self.pytest_nodeid, {"end_time": time.time()}
)

def end_run(self, run_tree, outputs: Any) -> Future:
def end_run(self, run_tree, outputs: Any) -> None:
if not (outputs is None or isinstance(outputs, dict)):
outputs = {"output": outputs}
end_time = datetime.datetime.now(datetime.timezone.utc)
return self.test_suite.end_run(
self.test_suite.end_run(
run_tree,
self.example_id,
outputs,
Expand Down
2 changes: 1 addition & 1 deletion python/pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[tool.poetry]
name = "langsmith"
version = "0.3.0"
version = "0.3.1"
description = "Client library to connect to the LangSmith LLM Tracing and Evaluation Platform."
authors = ["LangChain <support@langchain.dev>"]
license = "MIT"
Expand Down

0 comments on commit 8ce0bbf

Please sign in to comment.