lmnr 0.4.48__tar.gz → 0.4.49__tar.gz
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-0.4.48 → lmnr-0.4.49}/PKG-INFO +29 -29
- {lmnr-0.4.48 → lmnr-0.4.49}/pyproject.toml +30 -30
- lmnr-0.4.49/src/lmnr/cli.py +101 -0
- {lmnr-0.4.48 → lmnr-0.4.49}/src/lmnr/sdk/evaluations.py +15 -6
- {lmnr-0.4.48 → lmnr-0.4.49}/src/lmnr/sdk/laminar.py +1 -9
- {lmnr-0.4.48 → lmnr-0.4.49}/src/lmnr/sdk/log.py +24 -1
- lmnr-0.4.48/src/lmnr/cli.py +0 -53
- {lmnr-0.4.48 → lmnr-0.4.49}/LICENSE +0 -0
- {lmnr-0.4.48 → lmnr-0.4.49}/README.md +0 -0
- {lmnr-0.4.48 → lmnr-0.4.49}/src/lmnr/__init__.py +0 -0
- {lmnr-0.4.48 → lmnr-0.4.49}/src/lmnr/openllmetry_sdk/.flake8 +0 -0
- {lmnr-0.4.48 → lmnr-0.4.49}/src/lmnr/openllmetry_sdk/.python-version +0 -0
- {lmnr-0.4.48 → lmnr-0.4.49}/src/lmnr/openllmetry_sdk/__init__.py +0 -0
- {lmnr-0.4.48 → lmnr-0.4.49}/src/lmnr/openllmetry_sdk/config/__init__.py +0 -0
- {lmnr-0.4.48 → lmnr-0.4.49}/src/lmnr/openllmetry_sdk/decorators/__init__.py +0 -0
- {lmnr-0.4.48 → lmnr-0.4.49}/src/lmnr/openllmetry_sdk/decorators/base.py +0 -0
- {lmnr-0.4.48 → lmnr-0.4.49}/src/lmnr/openllmetry_sdk/instruments.py +0 -0
- {lmnr-0.4.48 → lmnr-0.4.49}/src/lmnr/openllmetry_sdk/tracing/__init__.py +0 -0
- {lmnr-0.4.48 → lmnr-0.4.49}/src/lmnr/openllmetry_sdk/tracing/attributes.py +0 -0
- {lmnr-0.4.48 → lmnr-0.4.49}/src/lmnr/openllmetry_sdk/tracing/content_allow_list.py +0 -0
- {lmnr-0.4.48 → lmnr-0.4.49}/src/lmnr/openllmetry_sdk/tracing/context_manager.py +0 -0
- {lmnr-0.4.48 → lmnr-0.4.49}/src/lmnr/openllmetry_sdk/tracing/tracing.py +0 -0
- {lmnr-0.4.48 → lmnr-0.4.49}/src/lmnr/openllmetry_sdk/utils/__init__.py +0 -0
- {lmnr-0.4.48 → lmnr-0.4.49}/src/lmnr/openllmetry_sdk/utils/in_memory_span_exporter.py +0 -0
- {lmnr-0.4.48 → lmnr-0.4.49}/src/lmnr/openllmetry_sdk/utils/json_encoder.py +0 -0
- {lmnr-0.4.48 → lmnr-0.4.49}/src/lmnr/openllmetry_sdk/utils/package_check.py +0 -0
- {lmnr-0.4.48 → lmnr-0.4.49}/src/lmnr/openllmetry_sdk/version.py +0 -0
- {lmnr-0.4.48 → lmnr-0.4.49}/src/lmnr/sdk/__init__.py +0 -0
- {lmnr-0.4.48 → lmnr-0.4.49}/src/lmnr/sdk/datasets.py +0 -0
- {lmnr-0.4.48 → lmnr-0.4.49}/src/lmnr/sdk/decorators.py +0 -0
- {lmnr-0.4.48 → lmnr-0.4.49}/src/lmnr/sdk/eval_control.py +0 -0
- {lmnr-0.4.48 → lmnr-0.4.49}/src/lmnr/sdk/types.py +0 -0
- {lmnr-0.4.48 → lmnr-0.4.49}/src/lmnr/sdk/utils.py +0 -0
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.1
|
2
2
|
Name: lmnr
|
3
|
-
Version: 0.4.
|
3
|
+
Version: 0.4.49
|
4
4
|
Summary: Python SDK for Laminar AI
|
5
5
|
License: Apache-2.0
|
6
6
|
Author: lmnr.ai
|
@@ -44,35 +44,35 @@ Requires-Dist: deprecated (>=1.0)
|
|
44
44
|
Requires-Dist: opentelemetry-api (>=1.28.0)
|
45
45
|
Requires-Dist: opentelemetry-exporter-otlp-proto-grpc (>=1.28.0)
|
46
46
|
Requires-Dist: opentelemetry-exporter-otlp-proto-http (>=1.28.0)
|
47
|
-
Requires-Dist: opentelemetry-instrumentation-alephalpha (>=0.
|
48
|
-
Requires-Dist: opentelemetry-instrumentation-anthropic (>=0.
|
49
|
-
Requires-Dist: opentelemetry-instrumentation-bedrock (>=0.
|
50
|
-
Requires-Dist: opentelemetry-instrumentation-chromadb (>=0.
|
51
|
-
Requires-Dist: opentelemetry-instrumentation-cohere (>=0.
|
52
|
-
Requires-Dist: opentelemetry-instrumentation-google-generativeai (>=0.
|
53
|
-
Requires-Dist: opentelemetry-instrumentation-groq (>=0.
|
54
|
-
Requires-Dist: opentelemetry-instrumentation-haystack (>=0.
|
55
|
-
Requires-Dist: opentelemetry-instrumentation-lancedb (>=0.
|
56
|
-
Requires-Dist: opentelemetry-instrumentation-langchain (>=0.
|
57
|
-
Requires-Dist: opentelemetry-instrumentation-llamaindex (>=0.
|
58
|
-
Requires-Dist: opentelemetry-instrumentation-marqo (>=0.
|
59
|
-
Requires-Dist: opentelemetry-instrumentation-milvus (>=0.
|
60
|
-
Requires-Dist: opentelemetry-instrumentation-mistralai (>=0.
|
61
|
-
Requires-Dist: opentelemetry-instrumentation-ollama (>=0.
|
47
|
+
Requires-Dist: opentelemetry-instrumentation-alephalpha (>=0.34.0) ; extra == "all" or extra == "alephalpha"
|
48
|
+
Requires-Dist: opentelemetry-instrumentation-anthropic (>=0.34.0) ; extra == "all" or extra == "anthropic"
|
49
|
+
Requires-Dist: opentelemetry-instrumentation-bedrock (>=0.34.0) ; extra == "all" or extra == "bedrock"
|
50
|
+
Requires-Dist: opentelemetry-instrumentation-chromadb (>=0.34.0) ; extra == "all" or extra == "chromadb"
|
51
|
+
Requires-Dist: opentelemetry-instrumentation-cohere (>=0.34.0) ; extra == "all" or extra == "cohere"
|
52
|
+
Requires-Dist: opentelemetry-instrumentation-google-generativeai (>=0.34.0) ; extra == "all" or extra == "google-generativeai"
|
53
|
+
Requires-Dist: opentelemetry-instrumentation-groq (>=0.34.0) ; extra == "all" or extra == "groq"
|
54
|
+
Requires-Dist: opentelemetry-instrumentation-haystack (>=0.34.0) ; extra == "all" or extra == "haystack"
|
55
|
+
Requires-Dist: opentelemetry-instrumentation-lancedb (>=0.34.0) ; extra == "all" or extra == "lancedb"
|
56
|
+
Requires-Dist: opentelemetry-instrumentation-langchain (>=0.34.0) ; extra == "all" or extra == "langchain"
|
57
|
+
Requires-Dist: opentelemetry-instrumentation-llamaindex (>=0.34.0) ; extra == "all" or extra == "llamaindex"
|
58
|
+
Requires-Dist: opentelemetry-instrumentation-marqo (>=0.34.0) ; extra == "all" or extra == "marqo"
|
59
|
+
Requires-Dist: opentelemetry-instrumentation-milvus (>=0.34.0) ; extra == "all" or extra == "milvus"
|
60
|
+
Requires-Dist: opentelemetry-instrumentation-mistralai (>=0.34.0) ; extra == "all" or extra == "mistralai"
|
61
|
+
Requires-Dist: opentelemetry-instrumentation-ollama (>=0.34.0) ; extra == "all" or extra == "ollama"
|
62
62
|
Requires-Dist: opentelemetry-instrumentation-openai (>=0.33.12) ; extra == "all" or extra == "openai"
|
63
|
-
Requires-Dist: opentelemetry-instrumentation-pinecone (>=0.
|
64
|
-
Requires-Dist: opentelemetry-instrumentation-qdrant (>=0.
|
65
|
-
Requires-Dist: opentelemetry-instrumentation-replicate (>=0.
|
66
|
-
Requires-Dist: opentelemetry-instrumentation-requests (>=0.
|
67
|
-
Requires-Dist: opentelemetry-instrumentation-sagemaker (>=0.
|
68
|
-
Requires-Dist: opentelemetry-instrumentation-sqlalchemy (>=0.
|
69
|
-
Requires-Dist: opentelemetry-instrumentation-threading (>=0.
|
70
|
-
Requires-Dist: opentelemetry-instrumentation-together (>=0.
|
71
|
-
Requires-Dist: opentelemetry-instrumentation-transformers (>=0.
|
72
|
-
Requires-Dist: opentelemetry-instrumentation-urllib3 (>=0.
|
73
|
-
Requires-Dist: opentelemetry-instrumentation-vertexai (>=0.
|
74
|
-
Requires-Dist: opentelemetry-instrumentation-watsonx (>=0.
|
75
|
-
Requires-Dist: opentelemetry-instrumentation-weaviate (>=0.
|
63
|
+
Requires-Dist: opentelemetry-instrumentation-pinecone (>=0.34.0) ; extra == "all" or extra == "pinecone"
|
64
|
+
Requires-Dist: opentelemetry-instrumentation-qdrant (>=0.34.0) ; extra == "all" or extra == "qdrant"
|
65
|
+
Requires-Dist: opentelemetry-instrumentation-replicate (>=0.34.0) ; extra == "all" or extra == "replicate"
|
66
|
+
Requires-Dist: opentelemetry-instrumentation-requests (>=0.50b0)
|
67
|
+
Requires-Dist: opentelemetry-instrumentation-sagemaker (>=0.34.0) ; extra == "all" or extra == "sagemaker"
|
68
|
+
Requires-Dist: opentelemetry-instrumentation-sqlalchemy (>=0.50b0)
|
69
|
+
Requires-Dist: opentelemetry-instrumentation-threading (>=0.50b0)
|
70
|
+
Requires-Dist: opentelemetry-instrumentation-together (>=0.34.0) ; extra == "all" or extra == "together"
|
71
|
+
Requires-Dist: opentelemetry-instrumentation-transformers (>=0.34.0) ; extra == "all" or extra == "transformers"
|
72
|
+
Requires-Dist: opentelemetry-instrumentation-urllib3 (>=0.50b0)
|
73
|
+
Requires-Dist: opentelemetry-instrumentation-vertexai (>=0.34.0) ; extra == "all" or extra == "vertexai"
|
74
|
+
Requires-Dist: opentelemetry-instrumentation-watsonx (>=0.34.0) ; extra == "all" or extra == "watsonx"
|
75
|
+
Requires-Dist: opentelemetry-instrumentation-weaviate (>=0.34.0) ; extra == "all" or extra == "weaviate"
|
76
76
|
Requires-Dist: opentelemetry-sdk (>=1.28.0)
|
77
77
|
Requires-Dist: opentelemetry-semantic-conventions-ai (==0.4.2)
|
78
78
|
Requires-Dist: pydantic (>=2.7)
|
@@ -6,7 +6,7 @@
|
|
6
6
|
|
7
7
|
[project]
|
8
8
|
name = "lmnr"
|
9
|
-
version = "0.4.
|
9
|
+
version = "0.4.49"
|
10
10
|
description = "Python SDK for Laminar AI"
|
11
11
|
authors = [
|
12
12
|
{ name = "lmnr.ai", email = "founders@lmnr.ai" }
|
@@ -17,7 +17,7 @@ license = "Apache-2.0"
|
|
17
17
|
|
18
18
|
[tool.poetry]
|
19
19
|
name = "lmnr"
|
20
|
-
version = "0.4.
|
20
|
+
version = "0.4.49"
|
21
21
|
description = "Python SDK for Laminar AI"
|
22
22
|
authors = ["lmnr.ai"]
|
23
23
|
readme = "README.md"
|
@@ -32,41 +32,41 @@ opentelemetry-api = ">=1.28.0"
|
|
32
32
|
opentelemetry-sdk = ">=1.28.0"
|
33
33
|
opentelemetry-exporter-otlp-proto-http = ">=1.28.0"
|
34
34
|
opentelemetry-exporter-otlp-proto-grpc = ">=1.28.0"
|
35
|
-
opentelemetry-instrumentation-requests = "
|
36
|
-
opentelemetry-instrumentation-sqlalchemy = "
|
37
|
-
opentelemetry-instrumentation-urllib3 = "
|
38
|
-
opentelemetry-instrumentation-threading = "
|
35
|
+
opentelemetry-instrumentation-requests = ">=0.50b0"
|
36
|
+
opentelemetry-instrumentation-sqlalchemy = ">=0.50b0"
|
37
|
+
opentelemetry-instrumentation-urllib3 = ">=0.50b0"
|
38
|
+
opentelemetry-instrumentation-threading = ">=0.50b0"
|
39
39
|
opentelemetry-semantic-conventions-ai = "0.4.2"
|
40
40
|
deprecated = ">=1.0"
|
41
41
|
tqdm = ">=4.0"
|
42
42
|
argparse = ">=1.0"
|
43
43
|
aiohttp = ">=3.0"
|
44
44
|
tenacity = ">=8.0"
|
45
|
-
opentelemetry-instrumentation-alephalpha = {version = ">=0.
|
46
|
-
opentelemetry-instrumentation-anthropic = {version = ">=0.
|
47
|
-
opentelemetry-instrumentation-bedrock = {version = ">=0.
|
48
|
-
opentelemetry-instrumentation-chromadb = {version = ">=0.
|
49
|
-
opentelemetry-instrumentation-cohere = {version = ">=0.
|
50
|
-
opentelemetry-instrumentation-google-generativeai = {version = ">=0.
|
51
|
-
opentelemetry-instrumentation-groq = {version = ">=0.
|
52
|
-
opentelemetry-instrumentation-haystack = {version = ">=0.
|
53
|
-
opentelemetry-instrumentation-lancedb = {version = ">=0.
|
54
|
-
opentelemetry-instrumentation-langchain = {version = ">=0.
|
55
|
-
opentelemetry-instrumentation-llamaindex = {version = ">=0.
|
56
|
-
opentelemetry-instrumentation-marqo = {version = ">=0.
|
57
|
-
opentelemetry-instrumentation-milvus = {version = ">=0.
|
58
|
-
opentelemetry-instrumentation-mistralai = {version = ">=0.
|
59
|
-
opentelemetry-instrumentation-ollama = {version = ">=0.
|
45
|
+
opentelemetry-instrumentation-alephalpha = {version = ">=0.34.0", optional = true}
|
46
|
+
opentelemetry-instrumentation-anthropic = {version = ">=0.34.0", optional = true}
|
47
|
+
opentelemetry-instrumentation-bedrock = {version = ">=0.34.0", optional = true}
|
48
|
+
opentelemetry-instrumentation-chromadb = {version = ">=0.34.0", optional = true}
|
49
|
+
opentelemetry-instrumentation-cohere = {version = ">=0.34.0", optional = true}
|
50
|
+
opentelemetry-instrumentation-google-generativeai = {version = ">=0.34.0", optional = true}
|
51
|
+
opentelemetry-instrumentation-groq = {version = ">=0.34.0", optional = true}
|
52
|
+
opentelemetry-instrumentation-haystack = {version = ">=0.34.0", optional = true}
|
53
|
+
opentelemetry-instrumentation-lancedb = {version = ">=0.34.0", optional = true}
|
54
|
+
opentelemetry-instrumentation-langchain = {version = ">=0.34.0", optional = true}
|
55
|
+
opentelemetry-instrumentation-llamaindex = {version = ">=0.34.0", optional = true}
|
56
|
+
opentelemetry-instrumentation-marqo = {version = ">=0.34.0", optional = true}
|
57
|
+
opentelemetry-instrumentation-milvus = {version = ">=0.34.0", optional = true}
|
58
|
+
opentelemetry-instrumentation-mistralai = {version = ">=0.34.0", optional = true}
|
59
|
+
opentelemetry-instrumentation-ollama = {version = ">=0.34.0", optional = true}
|
60
60
|
opentelemetry-instrumentation-openai = {version = ">=0.33.12", optional = true}
|
61
|
-
opentelemetry-instrumentation-pinecone = {version = ">=0.
|
62
|
-
opentelemetry-instrumentation-qdrant = {version = ">=0.
|
63
|
-
opentelemetry-instrumentation-replicate = {version = ">=0.
|
64
|
-
opentelemetry-instrumentation-sagemaker = {version = ">=0.
|
65
|
-
opentelemetry-instrumentation-together = {version = ">=0.
|
66
|
-
opentelemetry-instrumentation-transformers = {version = ">=0.
|
67
|
-
opentelemetry-instrumentation-vertexai = {version = ">=0.
|
68
|
-
opentelemetry-instrumentation-watsonx = {version = ">=0.
|
69
|
-
opentelemetry-instrumentation-weaviate = {version = ">=0.
|
61
|
+
opentelemetry-instrumentation-pinecone = {version = ">=0.34.0", optional = true}
|
62
|
+
opentelemetry-instrumentation-qdrant = {version = ">=0.34.0", optional = true}
|
63
|
+
opentelemetry-instrumentation-replicate = {version = ">=0.34.0", optional = true}
|
64
|
+
opentelemetry-instrumentation-sagemaker = {version = ">=0.34.0", optional = true}
|
65
|
+
opentelemetry-instrumentation-together = {version = ">=0.34.0", optional = true}
|
66
|
+
opentelemetry-instrumentation-transformers = {version = ">=0.34.0", optional = true}
|
67
|
+
opentelemetry-instrumentation-vertexai = {version = ">=0.34.0", optional = true}
|
68
|
+
opentelemetry-instrumentation-watsonx = {version = ">=0.34.0", optional = true}
|
69
|
+
opentelemetry-instrumentation-weaviate = {version = ">=0.34.0", optional = true}
|
70
70
|
|
71
71
|
[tool.poetry.extras]
|
72
72
|
# List of all possible extras. You can specify one or more of these extras
|
@@ -0,0 +1,101 @@
|
|
1
|
+
from argparse import ArgumentParser
|
2
|
+
import asyncio
|
3
|
+
import importlib.util
|
4
|
+
import logging
|
5
|
+
import os
|
6
|
+
import re
|
7
|
+
import sys
|
8
|
+
|
9
|
+
from .sdk.eval_control import PREPARE_ONLY, EVALUATION_INSTANCE
|
10
|
+
from .sdk.log import ColorfulFormatter
|
11
|
+
|
12
|
+
LOG = logging.getLogger(__name__)
|
13
|
+
console_log_handler = logging.StreamHandler()
|
14
|
+
console_log_handler.setFormatter(ColorfulFormatter())
|
15
|
+
LOG.addHandler(console_log_handler)
|
16
|
+
|
17
|
+
|
18
|
+
EVAL_DIR = "evals"
|
19
|
+
|
20
|
+
|
21
|
+
async def run_evaluation(args):
|
22
|
+
sys.path.append(os.getcwd())
|
23
|
+
|
24
|
+
if args.file is None:
|
25
|
+
files = [
|
26
|
+
os.path.join(EVAL_DIR, f)
|
27
|
+
for f in os.listdir(EVAL_DIR)
|
28
|
+
if re.match(r".*_eval\.py$", f) or re.match(r"eval_.*\.py$", f)
|
29
|
+
]
|
30
|
+
if len(files) == 0:
|
31
|
+
LOG.error("No evaluation files found in evals directory")
|
32
|
+
return
|
33
|
+
files.sort()
|
34
|
+
LOG.info(f"Located {len(files)} evaluation files in {EVAL_DIR}")
|
35
|
+
|
36
|
+
else:
|
37
|
+
files = [args.file]
|
38
|
+
|
39
|
+
for file in files:
|
40
|
+
prep_token = PREPARE_ONLY.set(True)
|
41
|
+
LOG.info(f"Running evaluation from {file}")
|
42
|
+
try:
|
43
|
+
file = os.path.abspath(file)
|
44
|
+
name = "user_module" + file
|
45
|
+
|
46
|
+
spec = importlib.util.spec_from_file_location(name, file)
|
47
|
+
if spec is None or spec.loader is None:
|
48
|
+
LOG.error(f"Could not load module specification from {file}")
|
49
|
+
if args.fail_on_error:
|
50
|
+
return
|
51
|
+
continue
|
52
|
+
mod = importlib.util.module_from_spec(spec)
|
53
|
+
sys.modules[name] = mod
|
54
|
+
|
55
|
+
spec.loader.exec_module(mod)
|
56
|
+
evaluation = EVALUATION_INSTANCE.get()
|
57
|
+
if evaluation is None:
|
58
|
+
LOG.warning("Evaluation instance not found")
|
59
|
+
if args.fail_on_error:
|
60
|
+
return
|
61
|
+
continue
|
62
|
+
|
63
|
+
await evaluation.run()
|
64
|
+
finally:
|
65
|
+
PREPARE_ONLY.reset(prep_token)
|
66
|
+
|
67
|
+
|
68
|
+
def cli():
|
69
|
+
parser = ArgumentParser(
|
70
|
+
prog="lmnr",
|
71
|
+
description="CLI for Laminar. Call `lmnr [subcommand] --help` for more information on each subcommand.",
|
72
|
+
)
|
73
|
+
|
74
|
+
subparsers = parser.add_subparsers(title="subcommands", dest="subcommand")
|
75
|
+
|
76
|
+
parser_eval = subparsers.add_parser(
|
77
|
+
"eval",
|
78
|
+
description="Run an evaluation",
|
79
|
+
help="Run an evaluation",
|
80
|
+
)
|
81
|
+
parser_eval.add_argument(
|
82
|
+
"file",
|
83
|
+
nargs="?",
|
84
|
+
help="A file containing the evaluation to run."
|
85
|
+
+ "If no file name is provided, all evaluation files in the `evals` directory are run as long"
|
86
|
+
+ "as they match *_eval.py or eval_*.py",
|
87
|
+
default=None,
|
88
|
+
)
|
89
|
+
|
90
|
+
parser_eval.add_argument(
|
91
|
+
"--fail-on-error",
|
92
|
+
action="store_true",
|
93
|
+
default=False,
|
94
|
+
help="Fail on error",
|
95
|
+
)
|
96
|
+
|
97
|
+
parsed = parser.parse_args()
|
98
|
+
if parsed.subcommand == "eval":
|
99
|
+
asyncio.run(run_evaluation(parsed))
|
100
|
+
else:
|
101
|
+
parser.print_help()
|
@@ -29,8 +29,17 @@ from .utils import is_async
|
|
29
29
|
DEFAULT_BATCH_SIZE = 5
|
30
30
|
|
31
31
|
|
32
|
-
def get_evaluation_url(
|
33
|
-
|
32
|
+
def get_evaluation_url(
|
33
|
+
project_id: str, evaluation_id: str, base_url: str = "https://www.lmnr.ai"
|
34
|
+
):
|
35
|
+
url = base_url
|
36
|
+
if url.endswith("/"):
|
37
|
+
url = url[:-1]
|
38
|
+
if url.endswith("localhost") or url.endswith("127.0.0.1"):
|
39
|
+
# We best effort assume that the frontend is running on port 3000
|
40
|
+
# TODO: expose the frontend port?
|
41
|
+
url = url + ":3000"
|
42
|
+
return f"{url}/project/{project_id}/evaluations/{evaluation_id}"
|
34
43
|
|
35
44
|
|
36
45
|
def get_average_scores(results: list[EvaluationResultDatapoint]) -> dict[str, Numeric]:
|
@@ -49,8 +58,8 @@ def get_average_scores(results: list[EvaluationResultDatapoint]) -> dict[str, Nu
|
|
49
58
|
|
50
59
|
|
51
60
|
class EvaluationReporter:
|
52
|
-
def __init__(self):
|
53
|
-
|
61
|
+
def __init__(self, base_url: str = "https://www.lmnr.ai"):
|
62
|
+
self.base_url = base_url
|
54
63
|
|
55
64
|
def start(self, length: int):
|
56
65
|
self.cli_progress = tqdm(
|
@@ -71,7 +80,7 @@ class EvaluationReporter:
|
|
71
80
|
):
|
72
81
|
self.cli_progress.close()
|
73
82
|
print(
|
74
|
-
f"\nCheck the results at {get_evaluation_url(project_id, evaluation_id)}\n"
|
83
|
+
f"\nCheck the results at {get_evaluation_url(project_id, evaluation_id, self.base_url)}\n"
|
75
84
|
)
|
76
85
|
print("Average scores:")
|
77
86
|
for name, score in average_scores.items():
|
@@ -160,7 +169,7 @@ class Evaluation:
|
|
160
169
|
)
|
161
170
|
|
162
171
|
self.is_finished = False
|
163
|
-
self.reporter = EvaluationReporter()
|
172
|
+
self.reporter = EvaluationReporter(base_url)
|
164
173
|
if isinstance(data, list):
|
165
174
|
self.data = [
|
166
175
|
(Datapoint.model_validate(point) if isinstance(point, dict) else point)
|
@@ -136,15 +136,7 @@ class Laminar:
|
|
136
136
|
cls.__initialized = True
|
137
137
|
cls._initialize_logger()
|
138
138
|
|
139
|
-
if _processor is not None:
|
140
|
-
cls.__logger.warning(
|
141
|
-
"Using a custom span processor. This feature is added for tests only. "
|
142
|
-
"Any use of this feature outside of tests is not supported and "
|
143
|
-
"advised against."
|
144
|
-
)
|
145
|
-
|
146
139
|
Traceloop.init(
|
147
|
-
processor=_processor,
|
148
140
|
exporter=OTLPSpanExporter(
|
149
141
|
endpoint=cls.__base_grpc_url,
|
150
142
|
headers={"authorization": f"Bearer {cls.__project_api_key}"},
|
@@ -407,7 +399,7 @@ class Laminar:
|
|
407
399
|
)
|
408
400
|
yield span
|
409
401
|
|
410
|
-
#
|
402
|
+
# TODO: Figure out if this is necessary
|
411
403
|
try:
|
412
404
|
detach(ctx_token)
|
413
405
|
except Exception:
|
@@ -24,6 +24,29 @@ class CustomFormatter(logging.Formatter):
|
|
24
24
|
return formatter.format(record)
|
25
25
|
|
26
26
|
|
27
|
+
class ColorfulFormatter(logging.Formatter):
|
28
|
+
grey = "\x1b[38;20m"
|
29
|
+
green = "\x1b[32;20m"
|
30
|
+
yellow = "\x1b[33;20m"
|
31
|
+
red = "\x1b[31;20m"
|
32
|
+
bold_red = "\x1b[31;1m"
|
33
|
+
reset = "\x1b[0m"
|
34
|
+
fmt = "Laminar %(levelname)s: %(message)s"
|
35
|
+
|
36
|
+
FORMATS = {
|
37
|
+
logging.DEBUG: grey + fmt + reset,
|
38
|
+
logging.INFO: green + fmt + reset,
|
39
|
+
logging.WARNING: yellow + fmt + reset,
|
40
|
+
logging.ERROR: red + fmt + reset,
|
41
|
+
logging.CRITICAL: bold_red + fmt + reset,
|
42
|
+
}
|
43
|
+
|
44
|
+
def format(self, record: logging.LogRecord):
|
45
|
+
log_fmt = self.FORMATS.get(record.levelno)
|
46
|
+
formatter = logging.Formatter(log_fmt)
|
47
|
+
return formatter.format(record)
|
48
|
+
|
49
|
+
|
27
50
|
# For StreamHandlers / console
|
28
51
|
class VerboseColorfulFormatter(CustomFormatter):
|
29
52
|
def format(self, record):
|
@@ -32,7 +55,7 @@ class VerboseColorfulFormatter(CustomFormatter):
|
|
32
55
|
|
33
56
|
# For Verbose FileHandlers / files
|
34
57
|
class VerboseFormatter(CustomFormatter):
|
35
|
-
fmt = "%(asctime)s::%(name)s::%(levelname)s
|
58
|
+
fmt = "%(asctime)s::%(name)s::%(levelname)s: %(message)s (%(filename)s:%(lineno)d)"
|
36
59
|
|
37
60
|
def format(self, record):
|
38
61
|
formatter = logging.Formatter(self.fmt)
|
lmnr-0.4.48/src/lmnr/cli.py
DELETED
@@ -1,53 +0,0 @@
|
|
1
|
-
from argparse import ArgumentParser
|
2
|
-
import asyncio
|
3
|
-
import importlib.util
|
4
|
-
import os
|
5
|
-
import sys
|
6
|
-
|
7
|
-
from .sdk.eval_control import PREPARE_ONLY, EVALUATION_INSTANCE
|
8
|
-
|
9
|
-
|
10
|
-
async def run_evaluation(args):
|
11
|
-
sys.path.append(os.getcwd())
|
12
|
-
|
13
|
-
prep_token = PREPARE_ONLY.set(True)
|
14
|
-
try:
|
15
|
-
file = os.path.abspath(args.file)
|
16
|
-
name = "user_module"
|
17
|
-
|
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}")
|
21
|
-
mod = importlib.util.module_from_spec(spec)
|
22
|
-
sys.modules[name] = mod
|
23
|
-
|
24
|
-
spec.loader.exec_module(mod)
|
25
|
-
evaluation = EVALUATION_INSTANCE.get()
|
26
|
-
if evaluation is None:
|
27
|
-
raise RuntimeError("Evaluation instance not found")
|
28
|
-
|
29
|
-
await evaluation.run()
|
30
|
-
finally:
|
31
|
-
PREPARE_ONLY.reset(prep_token)
|
32
|
-
|
33
|
-
|
34
|
-
def cli():
|
35
|
-
parser = ArgumentParser(
|
36
|
-
prog="lmnr",
|
37
|
-
description="CLI for Laminar",
|
38
|
-
)
|
39
|
-
|
40
|
-
subparsers = parser.add_subparsers(title="subcommands", dest="subcommand")
|
41
|
-
|
42
|
-
parser_eval = subparsers.add_parser(
|
43
|
-
"eval",
|
44
|
-
description="Run an evaluation",
|
45
|
-
help="Run an evaluation",
|
46
|
-
)
|
47
|
-
parser_eval.add_argument("file", help="A file containing the evaluation to run")
|
48
|
-
|
49
|
-
parsed = parser.parse_args()
|
50
|
-
if parsed.subcommand == "eval":
|
51
|
-
asyncio.run(run_evaluation(parsed))
|
52
|
-
else:
|
53
|
-
parser.print_help()
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|