olca 0.2.32__py3-none-any.whl → 0.2.33__py3-none-any.whl
Sign up to get free protection for your applications and to get access to all the features.
- olca/fusewill_cli.py +42 -4
- olca/fusewill_utils.py +51 -11
- {olca-0.2.32.dist-info → olca-0.2.33.dist-info}/METADATA +1 -1
- olca-0.2.33.dist-info/RECORD +10 -0
- olca-0.2.32.dist-info/RECORD +0 -10
- {olca-0.2.32.dist-info → olca-0.2.33.dist-info}/LICENSE +0 -0
- {olca-0.2.32.dist-info → olca-0.2.33.dist-info}/WHEEL +0 -0
- {olca-0.2.32.dist-info → olca-0.2.33.dist-info}/entry_points.txt +0 -0
- {olca-0.2.32.dist-info → olca-0.2.33.dist-info}/top_level.txt +0 -0
olca/fusewill_cli.py
CHANGED
@@ -9,20 +9,36 @@ from fusewill_utils import (
|
|
9
9
|
create_prompt,
|
10
10
|
update_prompt,
|
11
11
|
delete_dataset,
|
12
|
-
get_trace_by_id
|
12
|
+
get_trace_by_id,
|
13
|
+
open_trace_in_browser,
|
14
|
+
print_traces,
|
15
|
+
print_trace
|
13
16
|
)
|
14
17
|
import dotenv
|
15
18
|
import json
|
19
|
+
import sys, termios, tty
|
16
20
|
#dotenv.load_dotenv()
|
17
21
|
|
22
|
+
def get_single_char_input():
|
23
|
+
fd = sys.stdin.fileno()
|
24
|
+
old_settings = termios.tcgetattr(fd)
|
25
|
+
try:
|
26
|
+
tty.setraw(fd)
|
27
|
+
ch = sys.stdin.read(1)
|
28
|
+
finally:
|
29
|
+
termios.tcsetattr(fd, termios.TCSADRAIN, old_settings)
|
30
|
+
return ch
|
31
|
+
|
18
32
|
def main():
|
19
33
|
parser = argparse.ArgumentParser(description="Langfuse CLI Wrapper")
|
20
34
|
subparsers = parser.add_subparsers(dest="command", help="Available commands")
|
21
35
|
|
22
36
|
# list_traces command
|
23
|
-
parser_list = subparsers.add_parser('list_traces', help='List traces')
|
37
|
+
parser_list = subparsers.add_parser('list_traces', help='List traces',aliases=['lt'])
|
24
38
|
parser_list.add_argument('--limit', type=int, default=100, help='Number of traces to fetch')
|
25
39
|
parser_list.add_argument('--output_dir', type=str, default='../output/traces', help='Directory to save traces')
|
40
|
+
parser_list.add_argument('-C','--comments', action='store_true', help='Show comments from the traces', default=False)
|
41
|
+
parser_list.add_argument('-W','--browse-interact', action='store_true', help='Ask user to open each trace in browser')
|
26
42
|
|
27
43
|
# create_dataset command
|
28
44
|
parser_create_dataset = subparsers.add_parser('create_dataset', help='Create a new dataset')
|
@@ -76,8 +92,29 @@ def main():
|
|
76
92
|
|
77
93
|
args = parser.parse_args()
|
78
94
|
|
79
|
-
if args.command == 'list_traces':
|
80
|
-
|
95
|
+
if args.command == 'list_traces' or args.command == 'lt':
|
96
|
+
show_comments_flag = args.comments if args.comments else False
|
97
|
+
traces = list_traces(
|
98
|
+
limit=args.limit,
|
99
|
+
output_dir=args.output_dir
|
100
|
+
)
|
101
|
+
if not args.browse_interact:
|
102
|
+
print_traces(traces, show_comments=show_comments_flag)
|
103
|
+
else:
|
104
|
+
for trace in traces.data:
|
105
|
+
print_trace(trace, show_comments=show_comments_flag)
|
106
|
+
print("Open this trace in browser (Y/N/Q)? ", end='', flush=True)
|
107
|
+
try:
|
108
|
+
resp = get_single_char_input().lower()
|
109
|
+
except KeyboardInterrupt:
|
110
|
+
print("\nExiting.")
|
111
|
+
sys.exit(0)
|
112
|
+
print(resp) # Echo the character
|
113
|
+
if resp == 'y':
|
114
|
+
open_trace_in_browser(trace.id)
|
115
|
+
elif resp == 'q':
|
116
|
+
print("Quitting.")
|
117
|
+
break
|
81
118
|
elif args.command == 'create_dataset':
|
82
119
|
metadata = json.loads(args.metadata)
|
83
120
|
create_dataset(name=args.name, description=args.description, metadata=metadata)
|
@@ -121,6 +158,7 @@ def main():
|
|
121
158
|
print(f"Trace ID: {trace.id}, Name: {trace.name}")
|
122
159
|
else:
|
123
160
|
parser.print_help()
|
161
|
+
exit(1)
|
124
162
|
|
125
163
|
if __name__ == '__main__':
|
126
164
|
main()
|
olca/fusewill_utils.py
CHANGED
@@ -2,12 +2,13 @@ import os
|
|
2
2
|
import sys
|
3
3
|
import json
|
4
4
|
import dotenv
|
5
|
+
import webbrowser
|
5
6
|
|
6
7
|
# Load .env from the current working directory
|
7
8
|
dotenv.load_dotenv(dotenv_path=os.path.join(os.getcwd(), ".env"))
|
8
9
|
|
9
10
|
# Try loading from home directory if variables are still not set
|
10
|
-
if not os.environ.get("LANGFUSE_PUBLIC_KEY") or not os.environ.get("LANGFUSE_SECRET_KEY"):
|
11
|
+
if not os.environ.get("LANGFUSE_PUBLIC_KEY") or not os.environ.get("LANGFUSE_SECRET_KEY") or not os.environ.get("LANGFUSE_HOST"):
|
11
12
|
dotenv.load_dotenv(dotenv_path=os.path.expanduser("~/.env"))
|
12
13
|
|
13
14
|
# Final check before exiting
|
@@ -16,6 +17,8 @@ if not os.environ.get("LANGFUSE_PUBLIC_KEY"):
|
|
16
17
|
missing_vars.append("LANGFUSE_PUBLIC_KEY")
|
17
18
|
if not os.environ.get("LANGFUSE_SECRET_KEY"):
|
18
19
|
missing_vars.append("LANGFUSE_SECRET_KEY")
|
20
|
+
if not os.environ.get("LANGFUSE_HOST"):
|
21
|
+
missing_vars.append("LANGFUSE_HOST")
|
19
22
|
|
20
23
|
if missing_vars:
|
21
24
|
print(f"Error: {', '.join(missing_vars)} not found.")
|
@@ -28,17 +31,49 @@ sys.path.insert(0, os.path.abspath(os.path.dirname(__file__)))
|
|
28
31
|
import json
|
29
32
|
|
30
33
|
import dotenv
|
34
|
+
_DEBUG_=False
|
35
|
+
if _DEBUG_:
|
36
|
+
print(os.environ.get("LANGFUSE_PUBLIC_KEY"))
|
37
|
+
print(os.environ.get("LANGFUSE_SECRET_KEY"))
|
38
|
+
print(os.environ.get("LANGFUSE_HOST"))
|
31
39
|
|
32
|
-
langfuse = Langfuse(
|
40
|
+
langfuse = Langfuse(
|
41
|
+
public_key=os.environ.get("LANGFUSE_PUBLIC_KEY"),
|
42
|
+
secret_key=os.environ.get("LANGFUSE_SECRET_KEY"),
|
43
|
+
host=os.environ.get("LANGFUSE_HOST")
|
44
|
+
)
|
33
45
|
|
34
|
-
def
|
46
|
+
def open_trace_in_browser(trace_id):
|
47
|
+
base_url = os.environ.get("LANGFUSE_HOST")
|
48
|
+
project_id = os.environ.get("LANGFUSE_PROJECT_ID")
|
49
|
+
if not base_url or not project_id:
|
50
|
+
print("Missing LANGFUSE_HOST or LANGFUSE_PROJECT_ID")
|
51
|
+
return
|
52
|
+
full_url = f"{base_url}/project/{project_id}/traces/{trace_id}"
|
53
|
+
print(f"Opening {full_url}")
|
54
|
+
webbrowser.open(full_url)
|
55
|
+
|
56
|
+
def print_trace(trace, show_comments=False):
|
57
|
+
print(f"<Trace \n\tat=\"{trace.createdAt}\" \n\tid=\"{trace.id}\" \n\tname=\"{trace.name}\" \n\tsession_id=\"{trace.session_id}\" \n\tprojectId=\"{trace.projectId}\" >")
|
58
|
+
print(f"<Input><CDATA[[\n{trace.input}\n]]></Input>")
|
59
|
+
print(f"<Output><CDATA[[\n{trace.output}\n]]></Output>")
|
60
|
+
print(f"<Metadata>{trace.metadata}</Metadata>")
|
61
|
+
if trace.scores:
|
62
|
+
print("<Scores>")
|
63
|
+
for score in trace.scores:
|
64
|
+
print(f"{score}")
|
65
|
+
print("</Scores>")
|
66
|
+
if show_comments and hasattr(trace, "comments"):
|
67
|
+
print(f"<Comments>\n{trace.comments}\n</Comments>")
|
68
|
+
print("</Trace>")
|
69
|
+
|
70
|
+
def print_traces(traces, show_comments=False):
|
71
|
+
for trace in traces.data:
|
72
|
+
print_trace(trace, show_comments)
|
73
|
+
|
74
|
+
def list_traces(limit=100, output_dir="../output/traces", show_comments=False):
|
35
75
|
traces = langfuse.get_traces(limit=limit)
|
36
76
|
os.makedirs(output_dir, exist_ok=True)
|
37
|
-
for trace in traces.data:
|
38
|
-
print(f"-----Trace ID: {trace.id}--Name: {trace.name}----------")
|
39
|
-
print(f"<output>{trace.output}</output>")
|
40
|
-
print(f"<Metadata>{trace.metadata}</Metadata>")
|
41
|
-
print("---")
|
42
77
|
return traces
|
43
78
|
|
44
79
|
def list_traces_by_score(score_name, min_value=None, max_value=None, limit=100):
|
@@ -62,11 +97,16 @@ def add_score_to_a_trace(trace_id, generation_id, name, value, data_type="NUMERI
|
|
62
97
|
comment=comment
|
63
98
|
)
|
64
99
|
|
65
|
-
def create_score(name, data_type, description=""):
|
66
|
-
langfuse.
|
100
|
+
def create_score(name, data_type, description="", possible_values=None, min_value=None, max_value=None):
|
101
|
+
langfuse.score(
|
67
102
|
name=name,
|
103
|
+
value="", # Provide a placeholder value
|
68
104
|
data_type=data_type,
|
69
|
-
description=description
|
105
|
+
description=description,
|
106
|
+
# For categorical:
|
107
|
+
**({"possible_values": possible_values} if data_type == "CATEGORICAL" and possible_values else {}),
|
108
|
+
# For numeric:
|
109
|
+
**({"min_value": min_value, "max_value": max_value} if data_type == "NUMERIC" and min_value is not None and max_value is not None else {})
|
70
110
|
)
|
71
111
|
|
72
112
|
def score_exists(name):
|
@@ -0,0 +1,10 @@
|
|
1
|
+
olca/__init__.py,sha256=3QyLLAys_KiiDIe-cfO_7QyY7di_qCaCS-sVziW2BOw,23
|
2
|
+
olca/fusewill_cli.py,sha256=-hq-uCQfx9Tkb8TTTJNgQS7hgigS9XDaNBL9CKAouMU,7415
|
3
|
+
olca/fusewill_utils.py,sha256=KBCa8Qntfj-M1WzS8hD6X8O_rN4JoL6ZW_CYCJ8X1pU,5224
|
4
|
+
olca/olcacli.py,sha256=s-dqJRE6xqQLG_qSwp8prahRV3vZNueEaK7OXgmU9wc,14885
|
5
|
+
olca-0.2.33.dist-info/LICENSE,sha256=gXf5dRMhNSbfLPYYTY_5hsZ1r7UU1OaKQEAQUhuIBkM,18092
|
6
|
+
olca-0.2.33.dist-info/METADATA,sha256=HHf928Hr4wplrAu3shaof-TAoluinuRCcVHHj7bfhlI,25311
|
7
|
+
olca-0.2.33.dist-info/WHEEL,sha256=GV9aMThwP_4oNCtvEC2ec3qUYutgWeAzklro_0m4WJQ,91
|
8
|
+
olca-0.2.33.dist-info/entry_points.txt,sha256=AhP5FMv6vnOq9C76V_vxRVIO50smnZXG4RIY47oD2_U,103
|
9
|
+
olca-0.2.33.dist-info/top_level.txt,sha256=bGDtAReS-xlS0F6MM-DyD0IQUqjNdWmgemnM3vNtrpI,5
|
10
|
+
olca-0.2.33.dist-info/RECORD,,
|
olca-0.2.32.dist-info/RECORD
DELETED
@@ -1,10 +0,0 @@
|
|
1
|
-
olca/__init__.py,sha256=3QyLLAys_KiiDIe-cfO_7QyY7di_qCaCS-sVziW2BOw,23
|
2
|
-
olca/fusewill_cli.py,sha256=ZFW2Oeq-gQpAaTIxzsztQWDMv7-R9WJTVcSspbTxpPk,5926
|
3
|
-
olca/fusewill_utils.py,sha256=TyyCVRkWeXaS14vh0BXGK-tj0ZPZ3_uQNnAOM-IE9FA,3405
|
4
|
-
olca/olcacli.py,sha256=s-dqJRE6xqQLG_qSwp8prahRV3vZNueEaK7OXgmU9wc,14885
|
5
|
-
olca-0.2.32.dist-info/LICENSE,sha256=gXf5dRMhNSbfLPYYTY_5hsZ1r7UU1OaKQEAQUhuIBkM,18092
|
6
|
-
olca-0.2.32.dist-info/METADATA,sha256=GioYe8rCVBdvGIw8QaIjkiMMQqvZfjYtRw85_z9ZcS4,25311
|
7
|
-
olca-0.2.32.dist-info/WHEEL,sha256=GV9aMThwP_4oNCtvEC2ec3qUYutgWeAzklro_0m4WJQ,91
|
8
|
-
olca-0.2.32.dist-info/entry_points.txt,sha256=AhP5FMv6vnOq9C76V_vxRVIO50smnZXG4RIY47oD2_U,103
|
9
|
-
olca-0.2.32.dist-info/top_level.txt,sha256=bGDtAReS-xlS0F6MM-DyD0IQUqjNdWmgemnM3vNtrpI,5
|
10
|
-
olca-0.2.32.dist-info/RECORD,,
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|