lmnr 0.4.37__py3-none-any.whl → 0.4.45__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.
lmnr/__init__.py CHANGED
@@ -7,6 +7,7 @@ from .sdk.types import (
7
7
  NodeInput,
8
8
  PipelineRunError,
9
9
  PipelineRunResponse,
10
+ TracingLevel,
10
11
  )
11
12
  from .sdk.decorators import observe
12
13
  from .openllmetry_sdk import Instruments
lmnr/cli.py CHANGED
@@ -1,26 +1,34 @@
1
1
  from argparse import ArgumentParser
2
2
  import asyncio
3
- import importlib
3
+ import importlib.util
4
4
  import os
5
5
  import sys
6
6
 
7
- from lmnr.sdk.evaluations import set_global_evaluation
7
+ from .sdk.eval_control import PREPARE_ONLY, EVALUATION_INSTANCE
8
8
 
9
9
 
10
- # TODO: Refactor this code
11
10
  async def run_evaluation(args):
12
- sys.path.insert(0, os.getcwd())
11
+ sys.path.append(os.getcwd())
13
12
 
14
- with set_global_evaluation(True):
13
+ prep_token = PREPARE_ONLY.set(True)
14
+ try:
15
15
  file = os.path.abspath(args.file)
16
+ name = "user_module"
16
17
 
17
- spec = importlib.util.spec_from_file_location("run_eval", file)
18
+ spec = importlib.util.spec_from_file_location(name, file)
19
+ if spec is None or spec.loader is None:
20
+ raise ImportError(f"Could not load module specification from {file}")
18
21
  mod = importlib.util.module_from_spec(spec)
22
+ sys.modules[name] = mod
23
+
19
24
  spec.loader.exec_module(mod)
25
+ evaluation = EVALUATION_INSTANCE.get()
26
+ if evaluation is None:
27
+ raise RuntimeError("Evaluation instance not found")
20
28
 
21
- from lmnr.sdk.evaluations import _evaluation
22
- evaluation = _evaluation
23
29
  await evaluation.run()
30
+ finally:
31
+ PREPARE_ONLY.reset(prep_token)
24
32
 
25
33
 
26
34
  def cli():
@@ -31,9 +39,15 @@ def cli():
31
39
 
32
40
  subparsers = parser.add_subparsers(title="subcommands", dest="subcommand")
33
41
 
34
- parser_eval = subparsers.add_parser("eval", description="Run an evaluation")
42
+ parser_eval = subparsers.add_parser(
43
+ "eval",
44
+ description="Run an evaluation",
45
+ help="Run an evaluation",
46
+ )
35
47
  parser_eval.add_argument("file", help="A file containing the evaluation to run")
36
- parser_eval.set_defaults(func=run_evaluation)
37
48
 
38
49
  parsed = parser.parse_args()
39
- asyncio.run(parsed.func(parsed))
50
+ if parsed.subcommand == "eval":
51
+ asyncio.run(run_evaluation(parsed))
52
+ else:
53
+ parser.print_help()
@@ -3,11 +3,13 @@ from functools import wraps
3
3
  import logging
4
4
  import os
5
5
  import pydantic
6
+ import traceback
6
7
  import types
7
8
  from typing import Any, Optional
8
9
 
9
10
  from opentelemetry import trace
10
11
  from opentelemetry import context as context_api
12
+ from opentelemetry.trace import Span
11
13
 
12
14
  from lmnr.sdk.utils import get_input_from_func_args, is_method
13
15
  from lmnr.openllmetry_sdk.tracing import get_tracer
@@ -69,7 +71,12 @@ def entity_method(
69
71
  except TypeError:
70
72
  pass
71
73
 
72
- res = fn(*args, **kwargs)
74
+ try:
75
+ res = fn(*args, **kwargs)
76
+ except Exception as e:
77
+ _process_exception(span, e)
78
+ span.end()
79
+ raise e
73
80
 
74
81
  # span will be ended in the generator
75
82
  if isinstance(res, types.GeneratorType):
@@ -131,7 +138,12 @@ def aentity_method(
131
138
  except TypeError:
132
139
  pass
133
140
 
134
- res = await fn(*args, **kwargs)
141
+ try:
142
+ res = await fn(*args, **kwargs)
143
+ except Exception as e:
144
+ _process_exception(span, e)
145
+ span.end()
146
+ raise e
135
147
 
136
148
  # span will be ended in the generator
137
149
  if isinstance(res, types.AsyncGeneratorType):
@@ -177,3 +189,17 @@ def _should_send_prompts():
177
189
  return (
178
190
  os.getenv("TRACELOOP_TRACE_CONTENT") or "true"
179
191
  ).lower() == "true" or context_api.get_value("override_enable_content_tracing")
192
+
193
+
194
+ def _process_exception(span: Span, e: Exception):
195
+ exception_path = [type(e).__module__] if type(e).__module__ != "builtins" else []
196
+ exception_path.append(type(e).__qualname__)
197
+ span.add_event(
198
+ "exception",
199
+ {
200
+ "exception.message": str(e),
201
+ "exception.type": ".".join(exception_path),
202
+ "exception.stacktrace": traceback.format_exc(),
203
+ "exception.escaped": True,
204
+ },
205
+ )
@@ -12,6 +12,7 @@ ASSOCIATION_PROPERTIES = "lmnr.association.properties"
12
12
  SESSION_ID = "session_id"
13
13
  USER_ID = "user_id"
14
14
  TRACE_TYPE = "trace_type"
15
+ TRACING_LEVEL = "tracing_level"
15
16
 
16
17
 
17
18
  # exposed to the user, configurable
@@ -10,6 +10,7 @@ from lmnr.openllmetry_sdk.tracing.attributes import (
10
10
  ASSOCIATION_PROPERTIES,
11
11
  SPAN_INSTRUMENTATION_SOURCE,
12
12
  SPAN_PATH,
13
+ TRACING_LEVEL,
13
14
  )
14
15
  from lmnr.openllmetry_sdk.tracing.content_allow_list import ContentAllowList
15
16
  from lmnr.openllmetry_sdk.utils import is_notebook
@@ -183,11 +184,7 @@ class TracerWrapper(object):
183
184
 
184
185
  @classmethod
185
186
  def verify_initialized(cls) -> bool:
186
- if hasattr(cls, "instance"):
187
- return True
188
-
189
- cls.__logger.warning("Laminar not initialized, make sure to initialize")
190
- return False
187
+ return hasattr(cls, "instance")
191
188
 
192
189
  def flush(self):
193
190
  self.__spans_processor.force_flush()
@@ -228,6 +225,9 @@ def remove_association_properties(properties: dict) -> None:
228
225
 
229
226
  def _set_association_properties_attributes(span, properties: dict) -> None:
230
227
  for key, value in properties.items():
228
+ if key == TRACING_LEVEL:
229
+ span.set_attribute(f"lmnr.internal.{TRACING_LEVEL}", value)
230
+ continue
231
231
  span.set_attribute(f"{ASSOCIATION_PROPERTIES}.{key}", value)
232
232
 
233
233
 
@@ -407,7 +407,9 @@ def init_instrumentations(
407
407
 
408
408
  def init_openai_instrumentor(should_enrich_metrics: bool):
409
409
  try:
410
- if is_package_installed("openai"):
410
+ if is_package_installed("openai") and is_package_installed(
411
+ "opentelemetry-instrumentation-openai"
412
+ ):
411
413
  from opentelemetry.instrumentation.openai import OpenAIInstrumentor
412
414
 
413
415
  instrumentor = OpenAIInstrumentor(
@@ -425,7 +427,9 @@ def init_openai_instrumentor(should_enrich_metrics: bool):
425
427
 
426
428
  def init_anthropic_instrumentor(should_enrich_metrics: bool):
427
429
  try:
428
- if is_package_installed("anthropic"):
430
+ if is_package_installed("anthropic") and is_package_installed(
431
+ "opentelemetry-instrumentation-anthropic"
432
+ ):
429
433
  from opentelemetry.instrumentation.anthropic import AnthropicInstrumentor
430
434
 
431
435
  instrumentor = AnthropicInstrumentor(
@@ -442,7 +446,9 @@ def init_anthropic_instrumentor(should_enrich_metrics: bool):
442
446
 
443
447
  def init_cohere_instrumentor():
444
448
  try:
445
- if is_package_installed("cohere"):
449
+ if is_package_installed("cohere") and is_package_installed(
450
+ "opentelemetry-instrumentation-cohere"
451
+ ):
446
452
  from opentelemetry.instrumentation.cohere import CohereInstrumentor
447
453
 
448
454
  instrumentor = CohereInstrumentor()
@@ -456,7 +462,9 @@ def init_cohere_instrumentor():
456
462
 
457
463
  def init_pinecone_instrumentor():
458
464
  try:
459
- if is_package_installed("pinecone"):
465
+ if is_package_installed("pinecone") and is_package_installed(
466
+ "opentelemetry-instrumentation-pinecone"
467
+ ):
460
468
  from opentelemetry.instrumentation.pinecone import PineconeInstrumentor
461
469
 
462
470
  instrumentor = PineconeInstrumentor()
@@ -470,7 +478,9 @@ def init_pinecone_instrumentor():
470
478
 
471
479
  def init_qdrant_instrumentor():
472
480
  try:
473
- if is_package_installed("qdrant_client"):
481
+ if is_package_installed("qdrant_client") and is_package_installed(
482
+ "opentelemetry-instrumentation-qdrant"
483
+ ):
474
484
  from opentelemetry.instrumentation.qdrant import QdrantInstrumentor
475
485
 
476
486
  instrumentor = QdrantInstrumentor()
@@ -483,7 +493,9 @@ def init_qdrant_instrumentor():
483
493
 
484
494
  def init_chroma_instrumentor():
485
495
  try:
486
- if is_package_installed("chromadb"):
496
+ if is_package_installed("chromadb") and is_package_installed(
497
+ "opentelemetry-instrumentation-chromadb"
498
+ ):
487
499
  from opentelemetry.instrumentation.chromadb import ChromaInstrumentor
488
500
 
489
501
  instrumentor = ChromaInstrumentor()
@@ -497,7 +509,9 @@ def init_chroma_instrumentor():
497
509
 
498
510
  def init_google_generativeai_instrumentor():
499
511
  try:
500
- if is_package_installed("google.generativeai"):
512
+ if is_package_installed("google.generativeai") and is_package_installed(
513
+ "opentelemetry-instrumentation-google-generativeai"
514
+ ):
501
515
  from opentelemetry.instrumentation.google_generativeai import (
502
516
  GoogleGenerativeAiInstrumentor,
503
517
  )
@@ -513,7 +527,9 @@ def init_google_generativeai_instrumentor():
513
527
 
514
528
  def init_haystack_instrumentor():
515
529
  try:
516
- if is_package_installed("haystack"):
530
+ if is_package_installed("haystack") and is_package_installed(
531
+ "opentelemetry-instrumentation-haystack"
532
+ ):
517
533
  from opentelemetry.instrumentation.haystack import HaystackInstrumentor
518
534
 
519
535
  instrumentor = HaystackInstrumentor()
@@ -527,7 +543,9 @@ def init_haystack_instrumentor():
527
543
 
528
544
  def init_langchain_instrumentor():
529
545
  try:
530
- if is_package_installed("langchain"):
546
+ if is_package_installed("langchain") and is_package_installed(
547
+ "opentelemetry-instrumentation-langchain"
548
+ ):
531
549
  from opentelemetry.instrumentation.langchain import LangchainInstrumentor
532
550
 
533
551
  instrumentor = LangchainInstrumentor()
@@ -543,7 +561,9 @@ def init_langchain_instrumentor():
543
561
 
544
562
  def init_mistralai_instrumentor():
545
563
  try:
546
- if is_package_installed("mistralai"):
564
+ if is_package_installed("mistralai") and is_package_installed(
565
+ "opentelemetry-instrumentation-mistralai"
566
+ ):
547
567
  from opentelemetry.instrumentation.mistralai import MistralAiInstrumentor
548
568
 
549
569
  instrumentor = MistralAiInstrumentor()
@@ -557,7 +577,9 @@ def init_mistralai_instrumentor():
557
577
 
558
578
  def init_ollama_instrumentor():
559
579
  try:
560
- if is_package_installed("ollama"):
580
+ if is_package_installed("ollama") and is_package_installed(
581
+ "opentelemetry-instrumentation-ollama"
582
+ ):
561
583
  from opentelemetry.instrumentation.ollama import OllamaInstrumentor
562
584
 
563
585
  instrumentor = OllamaInstrumentor()
@@ -571,7 +593,9 @@ def init_ollama_instrumentor():
571
593
 
572
594
  def init_transformers_instrumentor():
573
595
  try:
574
- if is_package_installed("transformers"):
596
+ if is_package_installed("transformers") and is_package_installed(
597
+ "opentelemetry-instrumentation-transformers"
598
+ ):
575
599
  from opentelemetry.instrumentation.transformers import (
576
600
  TransformersInstrumentor,
577
601
  )
@@ -587,7 +611,9 @@ def init_transformers_instrumentor():
587
611
 
588
612
  def init_together_instrumentor():
589
613
  try:
590
- if is_package_installed("together"):
614
+ if is_package_installed("together") and is_package_installed(
615
+ "opentelemetry-instrumentation-together"
616
+ ):
591
617
  from opentelemetry.instrumentation.together import TogetherAiInstrumentor
592
618
 
593
619
  instrumentor = TogetherAiInstrumentor()
@@ -601,7 +627,9 @@ def init_together_instrumentor():
601
627
 
602
628
  def init_llama_index_instrumentor():
603
629
  try:
604
- if is_package_installed("llama-index") or is_package_installed("llama_index"):
630
+ if (
631
+ is_package_installed("llama-index") or is_package_installed("llama_index")
632
+ ) and is_package_installed("opentelemetry-instrumentation-llamaindex"):
605
633
  from opentelemetry.instrumentation.llamaindex import LlamaIndexInstrumentor
606
634
 
607
635
  instrumentor = LlamaIndexInstrumentor()
@@ -615,7 +643,9 @@ def init_llama_index_instrumentor():
615
643
 
616
644
  def init_milvus_instrumentor():
617
645
  try:
618
- if is_package_installed("pymilvus"):
646
+ if is_package_installed("pymilvus") and is_package_installed(
647
+ "opentelemetry-instrumentation-milvus"
648
+ ):
619
649
  from opentelemetry.instrumentation.milvus import MilvusInstrumentor
620
650
 
621
651
  instrumentor = MilvusInstrumentor()
@@ -671,7 +701,9 @@ def init_pymysql_instrumentor():
671
701
 
672
702
  def init_bedrock_instrumentor(should_enrich_metrics: bool):
673
703
  try:
674
- if is_package_installed("boto3"):
704
+ if is_package_installed("boto3") and is_package_installed(
705
+ "opentelemetry-instrumentation-bedrock"
706
+ ):
675
707
  from opentelemetry.instrumentation.bedrock import BedrockInstrumentor
676
708
 
677
709
  instrumentor = BedrockInstrumentor(
@@ -687,7 +719,9 @@ def init_bedrock_instrumentor(should_enrich_metrics: bool):
687
719
 
688
720
  def init_replicate_instrumentor():
689
721
  try:
690
- if is_package_installed("replicate"):
722
+ if is_package_installed("replicate") and is_package_installed(
723
+ "opentelemetry-instrumentation-replicate"
724
+ ):
691
725
  from opentelemetry.instrumentation.replicate import ReplicateInstrumentor
692
726
 
693
727
  instrumentor = ReplicateInstrumentor()
@@ -701,7 +735,9 @@ def init_replicate_instrumentor():
701
735
 
702
736
  def init_vertexai_instrumentor():
703
737
  try:
704
- if is_package_installed("vertexai"):
738
+ if is_package_installed("vertexai") and is_package_installed(
739
+ "opentelemetry-instrumentation-vertexai"
740
+ ):
705
741
  from opentelemetry.instrumentation.vertexai import VertexAIInstrumentor
706
742
 
707
743
  instrumentor = VertexAIInstrumentor()
@@ -715,9 +751,10 @@ def init_vertexai_instrumentor():
715
751
 
716
752
  def init_watsonx_instrumentor():
717
753
  try:
718
- if is_package_installed("ibm-watsonx-ai") or is_package_installed(
719
- "ibm-watson-machine-learning"
720
- ):
754
+ if (
755
+ is_package_installed("ibm-watsonx-ai")
756
+ or is_package_installed("ibm-watson-machine-learning")
757
+ ) and is_package_installed("opentelemetry-instrumentation-watsonx"):
721
758
  from opentelemetry.instrumentation.watsonx import WatsonxInstrumentor
722
759
 
723
760
  instrumentor = WatsonxInstrumentor()
@@ -731,7 +768,9 @@ def init_watsonx_instrumentor():
731
768
 
732
769
  def init_weaviate_instrumentor():
733
770
  try:
734
- if is_package_installed("weaviate"):
771
+ if is_package_installed("weaviate") and is_package_installed(
772
+ "opentelemetry-instrumentation-weaviate"
773
+ ):
735
774
  from opentelemetry.instrumentation.weaviate import WeaviateInstrumentor
736
775
 
737
776
  instrumentor = WeaviateInstrumentor()
@@ -745,7 +784,9 @@ def init_weaviate_instrumentor():
745
784
 
746
785
  def init_alephalpha_instrumentor():
747
786
  try:
748
- if is_package_installed("aleph_alpha_client"):
787
+ if is_package_installed("aleph_alpha_client") and is_package_installed(
788
+ "opentelemetry-instrumentation-alephalpha"
789
+ ):
749
790
  from opentelemetry.instrumentation.alephalpha import AlephAlphaInstrumentor
750
791
 
751
792
  instrumentor = AlephAlphaInstrumentor()
@@ -759,7 +800,9 @@ def init_alephalpha_instrumentor():
759
800
 
760
801
  def init_marqo_instrumentor():
761
802
  try:
762
- if is_package_installed("marqo"):
803
+ if is_package_installed("marqo") and is_package_installed(
804
+ "opentelemetry-instrumentation-marqo"
805
+ ):
763
806
  from opentelemetry.instrumentation.marqo import MarqoInstrumentor
764
807
 
765
808
  instrumentor = MarqoInstrumentor()
@@ -773,7 +816,9 @@ def init_marqo_instrumentor():
773
816
 
774
817
  def init_lancedb_instrumentor():
775
818
  try:
776
- if is_package_installed("lancedb"):
819
+ if is_package_installed("lancedb") and is_package_installed(
820
+ "opentelemetry-instrumentation-lancedb"
821
+ ):
777
822
  from opentelemetry.instrumentation.lancedb import LanceInstrumentor
778
823
 
779
824
  instrumentor = LanceInstrumentor()
@@ -786,7 +831,9 @@ def init_lancedb_instrumentor():
786
831
 
787
832
  def init_redis_instrumentor():
788
833
  try:
789
- if is_package_installed("redis"):
834
+ if is_package_installed("redis") and is_package_installed(
835
+ "opentelemetry-instrumentation-redis"
836
+ ):
790
837
  from opentelemetry.instrumentation.redis import RedisInstrumentor
791
838
 
792
839
  instrumentor = RedisInstrumentor()
@@ -800,7 +847,9 @@ def init_redis_instrumentor():
800
847
 
801
848
  def init_groq_instrumentor():
802
849
  try:
803
- if is_package_installed("groq"):
850
+ if is_package_installed("groq") and is_package_installed(
851
+ "opentelemetry-instrumentation-groq"
852
+ ):
804
853
  from opentelemetry.instrumentation.groq import GroqInstrumentor
805
854
 
806
855
  instrumentor = GroqInstrumentor()
@@ -814,7 +863,9 @@ def init_groq_instrumentor():
814
863
 
815
864
  def init_sagemaker_instrumentor(should_enrich_metrics: bool):
816
865
  try:
817
- if is_package_installed("boto3"):
866
+ if is_package_installed("boto3") and is_package_installed(
867
+ "opentelemetry-instrumentation-sagemaker"
868
+ ):
818
869
  from opentelemetry.instrumentation.sagemaker import SageMakerInstrumentor
819
870
 
820
871
  instrumentor = SageMakerInstrumentor(
@@ -2,5 +2,6 @@ from importlib.metadata import distributions
2
2
 
3
3
  installed_packages = {dist.metadata["Name"].lower() for dist in distributions()}
4
4
 
5
+
5
6
  def is_package_installed(package_name: str) -> bool:
6
7
  return package_name.lower() in installed_packages
lmnr/sdk/datasets.py CHANGED
@@ -1,11 +1,9 @@
1
1
  from abc import ABC, abstractmethod
2
- import logging
2
+ import asyncio
3
3
 
4
4
  from .log import get_default_logger
5
5
  from .laminar import Laminar as L
6
- from .types import (
7
- Datapoint,
8
- )
6
+ from .types import Datapoint
9
7
 
10
8
  DEFAULT_FETCH_SIZE = 25
11
9
 
lmnr/sdk/decorators.py CHANGED
@@ -7,7 +7,7 @@ from opentelemetry.trace import INVALID_SPAN, get_current_span
7
7
  from typing import Callable, Optional, TypeVar, cast
8
8
  from typing_extensions import ParamSpec
9
9
 
10
- from lmnr.openllmetry_sdk.tracing.attributes import SESSION_ID, USER_ID
10
+ from lmnr.openllmetry_sdk.tracing.attributes import SESSION_ID
11
11
  from lmnr.openllmetry_sdk.tracing.tracing import update_association_properties
12
12
 
13
13
  from .utils import is_async
@@ -20,7 +20,6 @@ R = TypeVar("R")
20
20
  def observe(
21
21
  *,
22
22
  name: Optional[str] = None,
23
- user_id: Optional[str] = None,
24
23
  session_id: Optional[str] = None,
25
24
  ) -> Callable[[Callable[P, R]], Callable[P, R]]:
26
25
  """The main decorator entrypoint for Laminar. This is used to wrap
@@ -30,9 +29,6 @@ def observe(
30
29
  name (Optional[str], optional): Name of the span. Function
31
30
  name is used if not specified.
32
31
  Defaults to None.
33
- user_id (Optional[str], optional): User ID to associate
34
- with the span and the following context.
35
- Defaults to None.
36
32
  session_id (Optional[str], optional): Session ID to associate with the
37
33
  span and the following context. Defaults to None.
38
34
 
@@ -49,13 +45,9 @@ def observe(
49
45
  if current_span != INVALID_SPAN:
50
46
  if session_id is not None:
51
47
  current_span.set_attribute(SESSION_ID, session_id)
52
- if user_id is not None:
53
- current_span.set_attribute(USER_ID, user_id)
54
48
  association_properties = {}
55
49
  if session_id is not None:
56
50
  association_properties["session_id"] = session_id
57
- if user_id is not None:
58
- association_properties["user_id"] = user_id
59
51
  update_association_properties(association_properties)
60
52
  return (
61
53
  aentity_method(name=name)(func)
@@ -0,0 +1,4 @@
1
+ from contextvars import ContextVar
2
+
3
+ PREPARE_ONLY = ContextVar("__lmnr_prepare_only", default=False)
4
+ EVALUATION_INSTANCE = ContextVar("__lmnr_evaluation_instance", default=None)
lmnr/sdk/evaluations.py CHANGED
@@ -3,7 +3,6 @@ import re
3
3
  import sys
4
4
  import uuid
5
5
 
6
- from contextlib import contextmanager
7
6
  from tqdm import tqdm
8
7
  from typing import Any, Awaitable, Optional, Set, Union
9
8
 
@@ -11,6 +10,7 @@ from ..openllmetry_sdk.instruments import Instruments
11
10
  from ..openllmetry_sdk.tracing.attributes import SPAN_TYPE
12
11
 
13
12
  from .datasets import EvaluationDataset
13
+ from .eval_control import EVALUATION_INSTANCE, PREPARE_ONLY
14
14
  from .laminar import Laminar as L
15
15
  from .log import get_default_logger
16
16
  from .types import (
@@ -28,21 +28,6 @@ from .utils import is_async
28
28
 
29
29
  DEFAULT_BATCH_SIZE = 5
30
30
 
31
- _evaluation = None
32
- _set_global_evaluation = False
33
-
34
-
35
- @contextmanager
36
- def set_global_evaluation(set_global_evaluation: bool):
37
- global _set_global_evaluation
38
- original = _set_global_evaluation
39
- try:
40
- _set_global_evaluation = set_global_evaluation
41
- yield
42
- finally:
43
- _set_global_evaluation = original
44
- pass
45
-
46
31
 
47
32
  def get_evaluation_url(project_id: str, evaluation_id: str):
48
33
  return f"https://www.lmnr.ai/project/{project_id}/evaluations/{evaluation_id}"
@@ -198,15 +183,10 @@ class Evaluation:
198
183
  instruments=instruments,
199
184
  )
200
185
 
201
- def run(self) -> Union[None, Awaitable[None]]:
186
+ async def run(self) -> Awaitable[None]:
202
187
  if self.is_finished:
203
188
  raise Exception("Evaluation is already finished")
204
-
205
- loop = asyncio.get_event_loop()
206
- if loop.is_running():
207
- return loop.create_task(self._run())
208
- else:
209
- return loop.run_until_complete(self._run())
189
+ return await self._run()
210
190
 
211
191
  async def _run(self) -> None:
212
192
  self.reporter.start(len(self.data))
@@ -224,7 +204,7 @@ class Evaluation:
224
204
  for result_datapoint in result_datapoints:
225
205
  result_datapoint.human_evaluators = self.human_evaluators or {}
226
206
 
227
- evaluation = L.create_evaluation(
207
+ evaluation = await L.create_evaluation(
228
208
  data=result_datapoints, group_id=self.group_id, name=self.name
229
209
  )
230
210
  average_scores = get_average_scores(result_datapoints)
@@ -389,8 +369,11 @@ def evaluate(
389
369
  instruments=instruments,
390
370
  )
391
371
 
392
- global _evaluation
393
- if _set_global_evaluation:
394
- _evaluation = evaluation
372
+ if PREPARE_ONLY.get():
373
+ EVALUATION_INSTANCE.set(evaluation)
395
374
  else:
396
- return evaluation.run()
375
+ loop = asyncio.get_event_loop()
376
+ if loop.is_running():
377
+ return loop.run_until_complete(evaluation.run())
378
+ else:
379
+ return asyncio.run(evaluation.run())