Skip to content

Commit

Permalink
[Python] Respect enabled in context manager (#836)
Browse files Browse the repository at this point in the history
Previously, the trace() context manager would trace no matter what. Now,
respect the context var that's set if you use tracing_context()

Additionally, respect the enabled arg in @Traceable even if project_name
is manually defined.

Additionally, add more tests for async traceable invocations + use asyncio debug mode to log issues
  • Loading branch information
hinthornw authored Jul 8, 2024
1 parent 9b1fcc4 commit 200b11b
Show file tree
Hide file tree
Showing 9 changed files with 381 additions and 239 deletions.
2 changes: 1 addition & 1 deletion python/Makefile
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
.PHONY: tests lint format build publish doctest integration_tests integration_tests_fast evals

tests:
poetry run python -m pytest --disable-socket --allow-unix-socket -n auto --durations=10 tests/unit_tests
PYTHONDEVMODE=1 PYTHONASYNCIODEBUG=1 poetry run python -m pytest --disable-socket --allow-unix-socket -n auto --durations=10 tests/unit_tests

tests_watch:
poetry run ptw --now . -- -vv -x tests/unit_tests
Expand Down
6 changes: 4 additions & 2 deletions python/langsmith/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -266,7 +266,9 @@ def _dumps_json_single(
ensure_ascii=True,
).encode("utf-8")
try:
result = orjson.dumps(orjson.loads(result.decode("utf-8", errors="lossy")))
result = orjson.dumps(
orjson.loads(result.decode("utf-8", errors="surrogateescape"))
)
except orjson.JSONDecodeError:
result = _elide_surrogates(result)
return result
Expand Down Expand Up @@ -1238,7 +1240,6 @@ def create_run(
if not self._filter_for_sampling([run_create]):
return
run_create = self._run_transform(run_create, copy=True)
self._insert_runtime_env([run_create])
if revision_id is not None:
run_create["extra"]["metadata"]["revision_id"] = revision_id
if (
Expand All @@ -1250,6 +1251,7 @@ def create_run(
return self.tracing_queue.put(
TracingQueueItem(run_create["dotted_order"], "create", run_create)
)
self._insert_runtime_env([run_create])
self._create_run(run_create)

def _create_run(self, run_create: dict):
Expand Down
35 changes: 15 additions & 20 deletions python/langsmith/run_helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -700,24 +700,24 @@ def trace(
DeprecationWarning,
)
old_ctx = get_tracing_context()
is_disabled = old_ctx.get("enabled", True) is False
outer_tags = _TAGS.get()
outer_metadata = _METADATA.get()
outer_project = _PROJECT_NAME.get() or utils.get_tracer_project()
parent_run_ = _get_parent_run(
{"parent": parent, "run_tree": kwargs.get("run_tree"), "client": client}
)

# Merge and set context variables
# Merge context variables
tags_ = sorted(set((tags or []) + (outer_tags or [])))
_TAGS.set(tags_)
metadata = {**(metadata or {}), **(outer_metadata or {}), "ls_method": "trace"}
_METADATA.set(metadata)

extra_outer = extra or {}
extra_outer["metadata"] = metadata

project_name_ = project_name or outer_project
if parent_run_ is not None:
# If it's disabled, we break the tree
if parent_run_ is not None and not is_disabled:
new_run = parent_run_.create_child(
name=name,
run_id=run_id,
Expand All @@ -740,9 +740,12 @@ def trace(
tags=tags_,
client=client, # type: ignore[arg-type]
)
new_run.post()
_PARENT_RUN_TREE.set(new_run)
_PROJECT_NAME.set(project_name_)
if not is_disabled:
new_run.post()
_TAGS.set(tags_)
_METADATA.set(metadata)
_PARENT_RUN_TREE.set(new_run)
_PROJECT_NAME.set(project_name_)

try:
yield new_run
Expand All @@ -753,12 +756,14 @@ def trace(
tb = utils._format_exc()
tb = f"{e.__class__.__name__}: {e}\n\n{tb}"
new_run.end(error=tb)
new_run.patch()
if not is_disabled:
new_run.patch()
raise e
finally:
# Reset the old context
_set_tracing_context(old_ctx)
new_run.patch()
if not is_disabled:
new_run.patch()


def as_runnable(traceable_fn: Callable) -> Runnable:
Expand Down Expand Up @@ -933,11 +938,6 @@ def _container_end(
error_ = f"{repr(error)}\n\n{stacktrace}"
run_tree.end(outputs=outputs_, error=error_)
run_tree.patch()
if error:
try:
LOGGER.info(f"See trace: {run_tree.get_url()}")
except Exception:
pass
on_end = container.get("on_end")
if on_end is not None and callable(on_end):
try:
Expand Down Expand Up @@ -1027,12 +1027,7 @@ def _setup_run(
)
reference_example_id = langsmith_extra.get("reference_example_id")
id_ = langsmith_extra.get("run_id")
if (
not project_cv
and not reference_example_id
and not parent_run_
and not utils.tracing_is_enabled()
):
if not parent_run_ and not utils.tracing_is_enabled():
utils.log_once(
logging.DEBUG, "LangSmith tracing is enabled, returning original function."
)
Expand Down
2 changes: 2 additions & 0 deletions python/langsmith/run_trees.py
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,8 @@ def infer_defaults(cls, values: dict) -> dict:
values["events"] = []
if values.get("tags") is None:
values["tags"] = []
if values.get("outputs") is None:
values["outputs"] = {}
return values

@root_validator(pre=False)
Expand Down
Loading

0 comments on commit 200b11b

Please sign in to comment.