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 +1 -0
- lmnr/cli.py +25 -11
- lmnr/openllmetry_sdk/decorators/base.py +28 -2
- lmnr/openllmetry_sdk/tracing/attributes.py +1 -0
- lmnr/openllmetry_sdk/tracing/tracing.py +84 -33
- lmnr/openllmetry_sdk/utils/package_check.py +1 -0
- lmnr/sdk/datasets.py +2 -4
- lmnr/sdk/decorators.py +1 -9
- lmnr/sdk/eval_control.py +4 -0
- lmnr/sdk/evaluations.py +11 -28
- lmnr/sdk/laminar.py +172 -75
- lmnr/sdk/types.py +39 -4
- {lmnr-0.4.37.dist-info → lmnr-0.4.45.dist-info}/METADATA +93 -62
- {lmnr-0.4.37.dist-info → lmnr-0.4.45.dist-info}/RECORD +17 -16
- {lmnr-0.4.37.dist-info → lmnr-0.4.45.dist-info}/LICENSE +0 -0
- {lmnr-0.4.37.dist-info → lmnr-0.4.45.dist-info}/WHEEL +0 -0
- {lmnr-0.4.37.dist-info → lmnr-0.4.45.dist-info}/entry_points.txt +0 -0
lmnr/__init__.py
CHANGED
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
|
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.
|
11
|
+
sys.path.append(os.getcwd())
|
13
12
|
|
14
|
-
|
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(
|
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(
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
+
)
|
@@ -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
|
-
|
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
|
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
|
719
|
-
"ibm-
|
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(
|
lmnr/sdk/datasets.py
CHANGED
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
|
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)
|
lmnr/sdk/eval_control.py
ADDED
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) ->
|
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
|
-
|
393
|
-
|
394
|
-
_evaluation = evaluation
|
372
|
+
if PREPARE_ONLY.get():
|
373
|
+
EVALUATION_INSTANCE.set(evaluation)
|
395
374
|
else:
|
396
|
-
|
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())
|