1+ #!/usr/bin/env python3
2+ """
3+ Demo script for setting and verifying customer ID and tags in Judgment traces.
4+
5+ This script demonstrates how to set metadata (customer ID and tags) on traces
6+ and verifies that the metadata is correctly set and saved.
7+
8+ Usage:
9+ python customer_id_and_tags.py [--api-url API_URL] [--project PROJECT_NAME]
10+ """
11+
12+ import os
13+ import sys
14+ import json
15+ import random
16+ import logging
17+ import argparse
18+ from typing import List , Dict , Any , Optional , Tuple
19+ from pathlib import Path
20+
21+ # Setup logging
22+ logging .basicConfig (
23+ level = logging .INFO ,
24+ format = "%(asctime)s - %(name)s - %(levelname)s - %(message)s"
25+ )
26+ logger = logging .getLogger ("metadata-demo" )
27+
28+ try :
29+ from judgeval .common .tracer import Tracer
30+ from dotenv import load_dotenv
31+ except ImportError as e :
32+ logger .error (f"Required package not found: { e } " )
33+ logger .error ("Please install required packages: pip install judgeval python-dotenv" )
34+ sys .exit (1 )
35+
36+ # Initialize a global variable for the Tracer instance
37+ judgment = None
38+
39+
40+ def parse_arguments () -> argparse .Namespace :
41+ """Parse command line arguments."""
42+ parser = argparse .ArgumentParser (description = "Test customer ID and tags in Judgment traces" )
43+ parser .add_argument (
44+ "--api-url" ,
45+ default = None ,
46+ help = "Judgment API URL (default: uses .env or http://localhost:8000)"
47+ )
48+ parser .add_argument (
49+ "--project" ,
50+ default = "metadata-test" ,
51+ help = "Project name for the trace (default: metadata-test)"
52+ )
53+ return parser .parse_args ()
54+
55+
56+ def validate_environment () -> Tuple [Optional [str ], Optional [str ]]:
57+ """Validate that required environment variables are set."""
58+ # Load environment variables from .env file
59+ load_dotenv ()
60+
61+ api_key = os .getenv ("JUDGMENT_API_KEY" )
62+ org_id = os .getenv ("JUDGMENT_ORG_ID" )
63+
64+ if not api_key :
65+ logger .error ("JUDGMENT_API_KEY environment variable is not set" )
66+ return None , org_id
67+
68+ if not org_id :
69+ logger .error ("JUDGMENT_ORG_ID environment variable is not set" )
70+ return api_key , None
71+
72+ return api_key , org_id
73+
74+
75+ def get_customer_id () -> str :
76+ """Generate a random customer ID for testing."""
77+ return f"customer-{ random .randint (1000 , 9999 )} "
78+
79+
80+ def get_test_tags () -> List [str ]:
81+ """Generate a list of tags for testing."""
82+ all_tags = ["test" , "example" , "metadata" , "demo" , "development" ]
83+ # Select 2-4 random tags
84+ num_tags = random .randint (2 , min (4 , len (all_tags )))
85+ return random .sample (all_tags , num_tags )
86+
87+
88+ def save_trace_data (trace_data : Dict [str , Any ], filename : str = "trace_metadata.json" ) -> None :
89+ """Save trace data to a JSON file."""
90+ try :
91+ with open (filename , "w" ) as f :
92+ json .dump (trace_data , f , indent = 2 )
93+ logger .info (f"Trace metadata saved to { filename } " )
94+ except Exception as e :
95+ logger .error (f"Failed to save trace data to { filename } : { e } " )
96+
97+
98+ def test_metadata (tracer : Tracer , customer_id : str , tags : List [str ]) -> str :
99+ """Test setting and verifying customer ID and tags."""
100+ try :
101+ logger .info (f"Setting customer ID: { customer_id } " )
102+ logger .info (f"Setting tags: { tags } " )
103+
104+ # Create a trace context
105+ with tracer .trace (name = "test_metadata" ) as trace :
106+ # Set both customer ID and tags at once
107+ tracer .set_metadata (
108+ customer_id = customer_id ,
109+ tags = tags
110+ )
111+
112+ # Verify the metadata was set correctly
113+ current_trace = tracer .get_current_trace ()
114+ if current_trace is None :
115+ raise ValueError ("Failed to get current trace" )
116+
117+ if current_trace .customer_id != customer_id :
118+ logger .warning (f"Customer ID mismatch: expected '{ customer_id } ', got '{ current_trace .customer_id } '" )
119+ else :
120+ logger .info (f"Customer ID verified: { current_trace .customer_id } " )
121+
122+ if current_trace .tags != tags :
123+ logger .warning (f"Tags mismatch: expected { tags } , got { current_trace .tags } " )
124+ else :
125+ logger .info (f"Tags verified: { current_trace .tags } " )
126+
127+ # Print all metadata
128+ logger .info ("Printing trace metadata:" )
129+ tracer .print_metadata ()
130+
131+ # Do some work
132+ logger .info ("Performing test operations..." )
133+ result = f"Test completed with customer ID: { customer_id } and tags: { tags } "
134+
135+ # Save trace data to a file for inspection
136+ trace_data = {
137+ "trace_id" : current_trace .trace_id ,
138+ "name" : current_trace .name ,
139+ "project_name" : current_trace .project_name ,
140+ "created_at" : current_trace .start_time ,
141+ "customer_id" : current_trace .customer_id ,
142+ "tags" : current_trace .tags
143+ }
144+ save_trace_data (trace_data )
145+
146+ return result
147+ except Exception as e :
148+ logger .error (f"Error in test_metadata: { e } " )
149+ raise
150+
151+
152+ def main () -> int :
153+ """Main function."""
154+ args = parse_arguments ()
155+
156+ # Validate environment
157+ api_key , org_id = validate_environment ()
158+ if api_key is None or org_id is None :
159+ return 1
160+
161+ # Set API URL
162+ api_url = args .api_url or os .getenv ("JUDGMENT_API_URL" , "http://localhost:8000" )
163+ os .environ ["JUDGMENT_API_URL" ] = api_url
164+
165+ # Initialize Tracer
166+ try :
167+ tracer = Tracer (
168+ api_key = api_key ,
169+ organization_id = org_id ,
170+ project_name = args .project
171+ )
172+ except Exception as e :
173+ logger .error (f"Failed to initialize Tracer: { e } " )
174+ return 1
175+
176+ # Generate test data
177+ customer_id = get_customer_id ()
178+ tags = get_test_tags ()
179+
180+ print (f"\n === Metadata Test ===\n " )
181+ print (f"API URL: { api_url } " )
182+ print (f"Project: { args .project } " )
183+ print (f"Customer ID: { customer_id } " )
184+ print (f"Tags: { tags } \n " )
185+
186+ try :
187+ # Run the test function
188+ result = test_metadata (tracer , customer_id , tags )
189+ print (f"\n Result: { result } " )
190+ print ("\n Check the Judgment dashboard to verify the metadata was saved." )
191+ return 0
192+ except Exception as e :
193+ logger .error (f"Test failed: { e } " )
194+ print (f"\n Error: { e } " )
195+ return 1
196+
197+
198+ if __name__ == "__main__" :
199+ sys .exit (main ())
0 commit comments