Skip to content

Commit d05a526

Browse files
author
Andrei Bratu
committed
Fix unsafe ContextVar lookup
1 parent 34aab96 commit d05a526

File tree

2 files changed

+10
-2
lines changed

2 files changed

+10
-2
lines changed

src/humanloop/eval_utils/run.py

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -126,14 +126,19 @@ def _overloaded_log(
126126
CreateFlowLogResponse,
127127
CreateEvaluatorLogResponse,
128128
]:
129-
evaluation_context = evaluation_context_variable.get()
129+
try:
130+
evaluation_context = evaluation_context_variable.get()
131+
except LookupError:
132+
# If the Evaluation Context is not set, an Evaluation is not running
133+
evaluation_context = None
130134

131135
if _is_evaluated_file(
132136
evaluation_context=evaluation_context, # type: ignore
133137
log_args=kwargs,
134138
):
135139
# If the .log API user does not provide the source_datapoint_id or run_id,
136140
# override them with the values from the EvaluationContext
141+
# _is_evaluated_file ensures that evaluation_context is not None
137142
evaluation_context = typing.cast(
138143
EvaluationContext,
139144
evaluation_context,
@@ -157,7 +162,7 @@ def _overloaded_log(
157162
log_args=kwargs,
158163
):
159164
# Notify that the Log has been added to the Evaluation
160-
# evaluation_context cannot be None
165+
# _is_evaluated_file ensures that evaluation_context is not None
161166
evaluation_context = typing.cast(
162167
EvaluationContext,
163168
evaluation_context,
@@ -463,6 +468,7 @@ def upload_callback(log: dict):
463468
"process_datapoint on Thread %s: evaluating Datapoint %s with EvaluationContext %s",
464469
threading.get_ident(),
465470
datapoint_dict,
471+
# .get() is safe since process_datapoint is always called in the context of an Evaluation
466472
evaluation_context_variable.get(),
467473
)
468474
log_func = _get_log_func(
@@ -495,6 +501,7 @@ def upload_callback(log: dict):
495501
# throw error if it fails to serialize
496502
raise ValueError(f"Your {type_}'s `callable` must return a string or a JSON serializable object.")
497503

504+
# .get() is safe since process_datapoint is always called in the context of an Evaluation
498505
context_variable = evaluation_context_variable.get()
499506
if context_variable is not None:
500507
# Evaluation Context has not been consumed

src/humanloop/otel/exporter.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,7 @@ def is_evaluated_file(
8989
if not is_evaluated_file(spans[0], evaluation_context):
9090
evaluation_context = None
9191
except LookupError:
92+
# No ongoing Evaluation happening
9293
evaluation_context = None
9394
for span in spans:
9495
if is_humanloop_span(span):

0 commit comments

Comments
 (0)