judgeval 0.0.11__py3-none-any.whl → 0.0.12__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
judgeval/common/tracer.py CHANGED
@@ -557,7 +557,8 @@ class TraceClient:
557
557
  "overwrite": overwrite
558
558
  }
559
559
 
560
- if not empty_save:
560
+ # Execute asynchrous evaluation in the background
561
+ if not empty_save: # Only send to RabbitMQ if the trace is not empty
561
562
  connection = pika.BlockingConnection(
562
563
  pika.ConnectionParameters(host=RABBITMQ_HOST, port=RABBITMQ_PORT))
563
564
  channel = connection.channel()
@@ -588,23 +589,31 @@ class Tracer:
588
589
  cls._instance = super(Tracer, cls).__new__(cls)
589
590
  return cls._instance
590
591
 
591
- def __init__(self, api_key: str = os.getenv("JUDGMENT_API_KEY")):
592
+ def __init__(self, api_key: str = os.getenv("JUDGMENT_API_KEY"), project_name: str = "default_project"):
592
593
  if not hasattr(self, 'initialized'):
593
-
594
594
  if not api_key:
595
595
  raise ValueError("Tracer must be configured with a Judgment API key")
596
596
 
597
597
  self.api_key: str = api_key
598
+ self.project_name: str = project_name
598
599
  self.client: JudgmentClient = JudgmentClient(judgment_api_key=api_key)
599
600
  self.depth: int = 0
600
601
  self._current_trace: Optional[str] = None
601
602
  self.initialized: bool = True
603
+ elif hasattr(self, 'project_name') and self.project_name != project_name:
604
+ warnings.warn(
605
+ f"Attempting to initialize Tracer with project_name='{project_name}' but it was already initialized with "
606
+ f"project_name='{self.project_name}'. Due to the singleton pattern, the original project_name will be used. "
607
+ "To use a different project name, ensure the first Tracer initialization uses the desired project name.",
608
+ RuntimeWarning
609
+ )
602
610
 
603
611
  @contextmanager
604
- def trace(self, name: str, project_name: str = "default_project", overwrite: bool = False) -> Generator[TraceClient, None, None]:
612
+ def trace(self, name: str, project_name: str = None, overwrite: bool = False) -> Generator[TraceClient, None, None]:
605
613
  """Start a new trace context using a context manager"""
606
614
  trace_id = str(uuid.uuid4())
607
- trace = TraceClient(self, trace_id, name, project_name=project_name, overwrite=overwrite)
615
+ project = project_name if project_name is not None else self.project_name
616
+ trace = TraceClient(self, trace_id, name, project_name=project, overwrite=overwrite)
608
617
  prev_trace = self._current_trace
609
618
  self._current_trace = trace
610
619
 
@@ -623,28 +632,40 @@ class Tracer:
623
632
  """
624
633
  return self._current_trace
625
634
 
626
- def observe(self, func=None, *, name=None, span_type: SpanType = "span"):
635
+ def observe(self, func=None, *, name=None, span_type: SpanType = "span", project_name: str = None, overwrite: bool = False):
627
636
  """
628
637
  Decorator to trace function execution with detailed entry/exit information.
629
638
 
630
639
  Args:
631
- func: The function to trace
632
- name: Optional custom name for the function
633
- span_type: The type of span to use for this observation (default: "span")
640
+ func: The function to decorate
641
+ name: Optional custom name for the span (defaults to function name)
642
+ span_type: Type of span (default "span")
643
+ project_name: Optional project name override
644
+ overwrite: Whether to overwrite existing traces
634
645
  """
635
646
  if func is None:
636
- return lambda f: self.observe(f, name=name, span_type=span_type)
647
+ return lambda f: self.observe(f, name=name, span_type=span_type, project_name=project_name, overwrite=overwrite)
648
+
649
+ # Use provided name or fall back to function name
650
+ span_name = name or func.__name__
637
651
 
638
652
  if asyncio.iscoroutinefunction(func):
639
653
  @functools.wraps(func)
640
654
  async def async_wrapper(*args, **kwargs):
655
+ # If there's already a trace, use it. Otherwise create a new one
641
656
  if self._current_trace:
642
- span_name = name or func.__name__
643
-
644
- with self._current_trace.span(span_name, span_type=span_type) as span:
645
- # Set the span type
646
- span.span_type = span_type
647
-
657
+ trace = self._current_trace
658
+ else:
659
+ trace_id = str(uuid.uuid4())
660
+ trace_name = str(uuid.uuid4())
661
+ project = project_name if project_name is not None else self.project_name
662
+ trace = TraceClient(self, trace_id, trace_name, project_name=project, overwrite=overwrite)
663
+ self._current_trace = trace
664
+ # Only save empty trace for the root call
665
+ trace.save(empty_save=True, overwrite=overwrite)
666
+
667
+ try:
668
+ with trace.span(span_name, span_type=span_type) as span:
648
669
  # Record inputs
649
670
  span.record_input({
650
671
  'args': list(args),
@@ -658,19 +679,30 @@ class Tracer:
658
679
  span.record_output(result)
659
680
 
660
681
  return result
661
-
662
- return await func(*args, **kwargs)
682
+ finally:
683
+ # Only save and cleanup if this is the root observe call
684
+ if self.depth == 0:
685
+ trace.save(empty_save=False, overwrite=overwrite)
686
+ self._current_trace = None
687
+
663
688
  return async_wrapper
664
689
  else:
665
690
  @functools.wraps(func)
666
691
  def wrapper(*args, **kwargs):
692
+ # If there's already a trace, use it. Otherwise create a new one
667
693
  if self._current_trace:
668
- span_name = name or func.__name__
669
-
670
- with self._current_trace.span(span_name, span_type=span_type) as span:
671
- # Set the span type
672
- span.span_type = span_type
673
-
694
+ trace = self._current_trace
695
+ else:
696
+ trace_id = str(uuid.uuid4())
697
+ trace_name = str(uuid.uuid4())
698
+ project = project_name if project_name is not None else self.project_name
699
+ trace = TraceClient(self, trace_id, trace_name, project_name=project, overwrite=overwrite)
700
+ self._current_trace = trace
701
+ # Only save empty trace for the root call
702
+ trace.save(empty_save=True, overwrite=overwrite)
703
+
704
+ try:
705
+ with trace.span(span_name, span_type=span_type) as span:
674
706
  # Record inputs
675
707
  span.record_input({
676
708
  'args': list(args),
@@ -684,8 +716,12 @@ class Tracer:
684
716
  span.record_output(result)
685
717
 
686
718
  return result
687
-
688
- return func(*args, **kwargs)
719
+ finally:
720
+ # Only save and cleanup if this is the root observe call
721
+ if self.depth == 0:
722
+ trace.save(empty_save=False, overwrite=overwrite)
723
+ self._current_trace = None
724
+
689
725
  return wrapper
690
726
 
691
727
  def wrap(client: Any) -> Any:
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: judgeval
3
- Version: 0.0.11
3
+ Version: 0.0.12
4
4
  Summary: Judgeval Package
5
5
  Project-URL: Homepage, https://github.com/JudgmentLabs/judgeval
6
6
  Project-URL: Issues, https://github.com/JudgmentLabs/judgeval/issues
@@ -7,7 +7,7 @@ judgeval/run_evaluation.py,sha256=YOQ6s9RuUrXPTgoYexf7r6Hl1QKIMSTdvHl9kw-ZMzw,20
7
7
  judgeval/common/__init__.py,sha256=7d24BRxtncpMj3AAJCj8RS7TqgjXmW777HVZH6-3sBs,289
8
8
  judgeval/common/exceptions.py,sha256=U-TxHLn7oVMezsMuoYouNDb2XuS8RCggfntYf5_6u4E,565
9
9
  judgeval/common/logger.py,sha256=QXN3UMymmKu2iMEMEgATLBnMDjGr_pE2iOSEFoICgg8,6092
10
- judgeval/common/tracer.py,sha256=wp-oGl8rdAe3_UXcvrEKFg7V6Vnvrnz9y_RVVgYOjCY,29934
10
+ judgeval/common/tracer.py,sha256=1WmHF5dGT-fesskT8BH39BZ65eQ9WURN49yGg9A6YKM,32397
11
11
  judgeval/common/utils.py,sha256=3WRyyX0tvnnj_VAVlEdtZrfzyWj6zfX04xdpCtE1m5Y,33736
12
12
  judgeval/data/__init__.py,sha256=YferxwmUqoBi18hrdgro0BD0h4pt20LAqISeUzGMcVU,474
13
13
  judgeval/data/api_example.py,sha256=vwWFbI6eJr5VgURCRbuSiMtEXLUbTCih_BcaqEBy-pg,4108
@@ -78,7 +78,7 @@ judgeval/scorers/judgeval_scorers/local_implementations/summarization/summarizat
78
78
  judgeval/scorers/judgeval_scorers/local_implementations/tool_correctness/__init__.py,sha256=JUB3TMqS1OHr6PqpIGqkyiBNbyfUaw7lZuUATjU3_ek,168
79
79
  judgeval/scorers/judgeval_scorers/local_implementations/tool_correctness/tool_correctness_scorer.py,sha256=CYGRJY5EuyICYzHrmFdLykwXakX8AC7G3Bhj7p6szfY,5493
80
80
  judgeval/tracer/__init__.py,sha256=wy3DYpH8U_z0GO_K_gOSkK0tTTD-u5eLDo0T5xIBoAc,147
81
- judgeval-0.0.11.dist-info/METADATA,sha256=WH8aPpUNCwE1Zr21qJ0H0WEVB_i_dilyLSbw9e5nXZo,1283
82
- judgeval-0.0.11.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
83
- judgeval-0.0.11.dist-info/licenses/LICENSE.md,sha256=tKmCg7k5QOmxPK19XMfzim04QiQJPmgIm0pAn55IJwk,11352
84
- judgeval-0.0.11.dist-info/RECORD,,
81
+ judgeval-0.0.12.dist-info/METADATA,sha256=QabQInkXXIceknwYzcLrqn9YbGk7nURNgseoD2TfM24,1283
82
+ judgeval-0.0.12.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
83
+ judgeval-0.0.12.dist-info/licenses/LICENSE.md,sha256=tKmCg7k5QOmxPK19XMfzim04QiQJPmgIm0pAn55IJwk,11352
84
+ judgeval-0.0.12.dist-info/RECORD,,