ModelArena / core /utils.py
vedanshmathur7's picture
Sync from GitHub via hub-sync
af8b301 verified
Raw History Blame Contribute Delete
5 kB
"""
Shared utility functions used across the project.
"""
from __future__ import annotations
import json
import logging
import os
from pathlib import Path
from typing import Any, Dict, List, Optional
# ---------------------------------------------------------------------------
# Logging setup
# ---------------------------------------------------------------------------
def setup_logging(level: str = "INFO") -> None:
"""Configure root logger with a clean format."""
logging.basicConfig(
level=getattr(logging, level.upper(), logging.INFO),
format="%(asctime)s | %(levelname)-8s | %(name)s | %(message)s",
datefmt="%H:%M:%S",
)
# ---------------------------------------------------------------------------
# Environment helpers
# ---------------------------------------------------------------------------
def get_env(key: str, default: Optional[str] = None, required: bool = False) -> Optional[str]:
"""
Retrieve an environment variable with optional validation.
Args:
key: Environment variable name
default: Default value if not set
required: Raise ValueError if not set and no default
"""
value = os.getenv(key, default)
if required and not value:
raise ValueError(
f"Required environment variable '{key}' is not set. "
f"Check your .env file."
)
return value
# ---------------------------------------------------------------------------
# JSON helpers
# ---------------------------------------------------------------------------
def load_json(path: Path | str) -> Any:
"""Load and return JSON from a file."""
path = Path(path)
if not path.exists():
raise FileNotFoundError(f"JSON file not found: {path}")
with open(path, "r", encoding="utf-8") as f:
return json.load(f)
def save_json(data: Any, path: Path | str, indent: int = 2) -> None:
"""Save data as JSON to a file, creating parent dirs as needed."""
path = Path(path)
path.parent.mkdir(parents=True, exist_ok=True)
with open(path, "w", encoding="utf-8") as f:
json.dump(data, f, indent=indent, ensure_ascii=False)
# ---------------------------------------------------------------------------
# Text helpers
# ---------------------------------------------------------------------------
def truncate(text: str, max_chars: int = 200, suffix: str = "...") -> str:
"""Truncate text to max_chars, appending suffix if truncated."""
if len(text) <= max_chars:
return text
return text[:max_chars - len(suffix)] + suffix
def count_words(text: str) -> int:
return len(text.split())
# ---------------------------------------------------------------------------
# Config loader
# ---------------------------------------------------------------------------
def load_config(config_path: Path | str = ".env") -> Dict[str, str]:
"""
Load key=value pairs from a .env file into a dict.
Does NOT set environment variables — use python-dotenv for that.
"""
config: Dict[str, str] = {}
path = Path(config_path)
if not path.exists():
return config
with open(path, "r") as f:
for line in f:
line = line.strip()
if not line or line.startswith("#"):
continue
if "=" in line:
key, _, value = line.partition("=")
config[key.strip()] = value.strip().strip('"').strip("'")
return config
# ---------------------------------------------------------------------------
# Eval dataset helpers
# ---------------------------------------------------------------------------
def load_eval_dataset(paths: List[Path | str]) -> List[dict]:
"""Load and merge multiple eval JSON files into a single list."""
combined: List[dict] = []
for path in paths:
try:
data = load_json(path)
if isinstance(data, list):
combined.extend(data)
elif isinstance(data, dict) and "prompts" in data:
combined.extend(data["prompts"])
except Exception as e:
logging.getLogger(__name__).warning("Could not load eval file %s: %s", path, e)
return combined
def format_cost_table(
oss_tokens: int,
frontier_tokens: int,
oss_cost_per_1k: float = 0.0,
frontier_cost_per_1k: float = 0.0006,
) -> str:
"""
Format a simple cost comparison table as a markdown string.
Default costs:
- OSS (self-hosted): $0.00 per 1k tokens
- Llama 3.1-8B via Groq: $0.00 (free tier) / ~$0.00005 per 1k tokens (paid)
"""
oss_cost = (oss_tokens / 1000) * oss_cost_per_1k
frontier_cost = (frontier_tokens / 1000) * frontier_cost_per_1k
return (
f"| Model | Tokens | Cost (USD) |\n"
f"|-------------|--------|------------|\n"
f"| OSS (local) | {oss_tokens:,} | ${oss_cost:.4f} |\n"
f"| Frontier | {frontier_tokens:,} | ${frontier_cost:.4f} |\n"
)