Spaces:
Runtime error
Runtime error
from typing import Optional, List | |
import argparse | |
import json | |
import glob | |
from pathlib import Path | |
from datetime import datetime | |
def get_latest_log() -> str: | |
"""Find the most recently modified log file in the current directory. | |
Returns: | |
str: Path to the most recently modified log file | |
Raises: | |
FileNotFoundError: If no log files are found in the current directory | |
""" | |
logs = list(Path(".").glob("api_usage_*.json")) | |
if not logs: | |
raise FileNotFoundError("No log files found in the current directory.") | |
return str(max(logs, key=lambda p: p.stat().st_mtime)) | |
def format_cost(entry: dict) -> str: | |
"""Format cost if available, otherwise return 'N/A' | |
Args: | |
entry: Log entry dictionary containing cost information | |
Returns: | |
str: Formatted cost string with $ and 4 decimal places, or 'N/A' if cost not found | |
""" | |
return f"${entry.get('cost', 'N/A'):.4f}" if "cost" in entry else "N/A" | |
def print_gpt4_entry(entry: dict) -> None: | |
"""Print entry for GPT-4 format | |
Args: | |
entry: Log entry dictionary in GPT-4 format containing model info, inputs and outputs | |
""" | |
print("\n=== Log Entry ===") | |
print(f"Model: {entry['model']}") | |
print(f"Case ID: {entry['case_id']}") | |
print(f"Question ID: {entry['question_id']}") | |
print("\n=== Model Input ===") | |
messages = entry["input"]["messages"] | |
print("System message:", messages[0]["content"]) | |
user_content = messages[1]["content"] | |
print("\nUser prompt:", user_content[0]["text"]) | |
print("\nImages provided:") | |
for content in user_content[1:]: | |
print(f" - {content['image_url']['url']}") | |
print("\n=== Model Output ===") | |
print(f"Answer: {entry['model_answer']}") | |
print(f"Correct: {entry['correct_answer']}") | |
print("\n=== Usage Stats ===") | |
print(f"Duration: {entry['duration']}s") | |
print(f"Cost: {format_cost(entry)}") | |
print( | |
f"Tokens: {entry['usage']['total_tokens']}", | |
f"(prompt: {entry['usage']['prompt_tokens']},", | |
f"completion: {entry['usage']['completion_tokens']})", | |
) | |
def print_llama_entry(entry: dict) -> None: | |
"""Print entry for Llama-3.2 format | |
Args: | |
entry: Log entry dictionary in Llama format containing model info, inputs and outputs | |
""" | |
print("\n=== Log Entry ===") | |
print(f"Model: {entry['model']}") | |
print(f"Case ID: {entry['case_id']}") | |
print(f"Question ID: {entry['question_id']}") | |
print("\n=== Model Input ===") | |
print(f"Question: {entry['input']['question_data']['question']}") | |
print("\nImages provided:") | |
for url in entry["input"]["image_urls"]: | |
print(f" - {url}") | |
if entry["input"]["image_captions"]: | |
print("\nImage captions:") | |
for caption in entry["input"]["image_captions"]: | |
if caption: | |
print(f" - {caption}") | |
print("\n=== Model Output ===") | |
print(f"Answer: {entry['model_answer']}") | |
print(f"Correct: {entry['correct_answer']}") | |
print("\n=== Usage Stats ===") | |
print(f"Duration: {entry['duration']}s") | |
if "usage" in entry: | |
print( | |
f"Tokens: {entry['usage']['total_tokens']}", | |
f"(prompt: {entry['usage']['prompt_tokens']},", | |
f"completion: {entry['usage']['completion_tokens']})", | |
) | |
def determine_model_type(entry: dict) -> str: | |
"""Determine the model type from the entry | |
Args: | |
entry: Log entry dictionary containing model information | |
Returns: | |
str: Model type - 'gpt4', 'llama', or 'unknown' | |
""" | |
model = entry.get("model", "").lower() | |
if "gpt-4" in model: | |
return "gpt4" | |
elif "llama" in model: | |
return "llama" | |
elif "chexagent" in model: | |
return "chexagent" | |
elif "medrax" in model: | |
return "medrax" | |
else: | |
return "unknown" | |
def print_log_entry( | |
log_file: Optional[str] = None, | |
num_entries: Optional[int] = None, | |
model_filter: Optional[str] = None, | |
) -> None: | |
"""Print log entries from the specified log file or the latest log file. | |
Args: | |
log_file: Path to the log file. If None, uses the latest log file. | |
num_entries: Number of entries to print. If None, prints all entries. | |
model_filter: Filter entries by model type ('gpt4' or 'llama'). If None, prints all. | |
""" | |
if log_file is None: | |
log_file = get_latest_log() | |
print(f"Using latest log file: {log_file}") | |
entries_printed = 0 | |
total_entries = 0 | |
filtered_entries = 0 | |
with open(log_file, "r") as f: | |
for line in f: | |
if line.startswith("HTTP"): | |
continue | |
try: | |
total_entries += 1 | |
entry = json.loads(line) | |
# Apply model filter if specified | |
model_type = determine_model_type(entry) | |
if model_filter and model_type != model_filter: | |
filtered_entries += 1 | |
continue | |
if model_type == "gpt4": | |
print_gpt4_entry(entry) | |
elif model_type == "llama": | |
print_llama_entry(entry) | |
else: | |
print(f"Unknown model type in entry: {entry['model']}") | |
continue | |
print("=" * 50) | |
entries_printed += 1 | |
if num_entries and entries_printed >= num_entries: | |
break | |
except (json.JSONDecodeError, KeyError) as e: | |
print(f"Error processing entry: {e}") | |
continue | |
print(f"\nSummary:") | |
print(f"Total entries: {total_entries}") | |
print(f"Entries printed: {entries_printed}") | |
if model_filter: | |
print(f"Entries filtered: {filtered_entries}") | |
def main() -> None: | |
"""Main entry point for the script""" | |
parser = argparse.ArgumentParser( | |
description="Parse and display log entries from API usage logs." | |
) | |
parser.add_argument("-l", "--log_file", nargs="?", help="Path to the log file (optional)") | |
parser.add_argument("-n", "--num_entries", type=int, help="Number of entries to display") | |
parser.add_argument( | |
"-m", | |
"--model", | |
choices=["gpt4", "llama"], | |
default="gpt4", | |
help="Model type to display (default: gpt4)", | |
) | |
args = parser.parse_args() | |
try: | |
print_log_entry(args.log_file, args.num_entries, args.model) | |
except FileNotFoundError as e: | |
print(f"Error: {e}") | |
exit(1) | |
if __name__ == "__main__": | |
main() | |