1from dataclasses import dataclass, field
2from collections import defaultdict
3from openai import OpenAI
4import tiktoken
5
6# GPT-4o-mini pricing (USD per 1M tokens, May 2025)
7PRICING = {
8 'gpt-4o-mini': {'input': 0.15, 'output': 0.60},
9 'gpt-4o': {'input': 5.00, 'output': 15.00},
10}
11
12@dataclass
13class UsageTracker:
14 totals: dict = field(default_factory=lambda: defaultdict(lambda: {'input': 0, 'output': 0}))
15
16 def record(self, model: str, prompt_tokens: int, completion_tokens: int) -> float:
17 self.totals[model]['input'] += prompt_tokens
18 self.totals[model]['output'] += completion_tokens
19 return self.cost(model, prompt_tokens, completion_tokens)
20
21 def cost(self, model: str, input_t: int, output_t: int) -> float:
22 p = PRICING.get(model, {'input': 0, 'output': 0})
23 return (input_t * p['input'] + output_t * p['output']) / 1_000_000
24
25 def report(self) -> None:
26 total_cost = 0
27 for model, counts in self.totals.items():
28 cost = self.cost(model, counts['input'], counts['output'])
29 total_cost += cost
30 print(f"{model}: {counts['input']+counts['output']} tokens → ${cost:.4f}")
31 print(f"Total cost: ${total_cost:.4f}")
32
33tracker = UsageTracker()
34client = OpenAI()
35
36def tracked_call(prompt: str, model="gpt-4o-mini") -> str:
37 response = client.chat.completions.create(
38 model=model, messages=[{"role": "user", "content": prompt}]
39 )
40 usage = response.usage
41 cost = tracker.record(model, usage.prompt_tokens, usage.completion_tokens)
42 print(f"This call: {usage.total_tokens} tokens, ${cost:.6f}")
43 return response.choices[0].message.content
44
45tracked_call("Explain async/await")
46tracked_call("What is Docker?")
47tracker.report()