Skip to content

Commit 9d12fd9

Browse files
authored
Don't throw needless warnings/errors about missing pricing info (#132)
* Don't throw needless warnings/errors about missing pricing info * Update changelog
1 parent baf9fc3 commit 9d12fd9

File tree

5 files changed

+26
-28
lines changed

5 files changed

+26
-28
lines changed

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
1313

1414
* Fixed an issue where `.chat()` wasn't streaming output properly in (the latest build of) Positron's Jupyter notebook. (#131)
1515

16+
* Needless warnings and errors are no longer thrown when model pricing info is unavailable. (#132)
17+
1618
## [0.9.0] - 2025-07-02
1719

1820
### New features

chatlas/_chat.py

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@
4444
from ._logging import log_tool_error
4545
from ._mcp_manager import MCPSessionManager
4646
from ._provider import Provider, StandardModelParams, SubmitInputArgsT
47-
from ._tokens import get_token_pricing
47+
from ._tokens import compute_cost, get_token_pricing
4848
from ._tools import Tool, ToolRejectError
4949
from ._turn import Turn, user_turn
5050
from ._typing_extensions import TypedDict, TypeGuard
@@ -2222,11 +2222,22 @@ def __str__(self):
22222222
def __repr__(self):
22232223
turns = self.get_turns(include_system_prompt=True)
22242224
tokens = self.get_tokens()
2225-
cost = self.get_cost()
22262225
tokens_asst = sum(u["tokens_total"] for u in tokens if u["role"] == "assistant")
22272226
tokens_user = sum(u["tokens_total"] for u in tokens if u["role"] == "user")
22282227

2229-
res = f"<Chat {self.provider.name}/{self.provider.model} turns={len(turns)} tokens={tokens_user}/{tokens_asst} ${round(cost, ndigits=2)}>"
2228+
res = f"<Chat {self.provider.name}/{self.provider.model} turns={len(turns)} tokens={tokens_user}/{tokens_asst}"
2229+
2230+
# Add cost info only if we can compute it
2231+
cost = compute_cost(
2232+
self.provider.name,
2233+
self.provider.model,
2234+
tokens_user,
2235+
tokens_asst,
2236+
)
2237+
if cost is not None:
2238+
res += f" ${round(cost, ndigits=2)}"
2239+
2240+
res += ">"
22302241
for turn in turns:
22312242
res += "\n" + turn.__repr__(indent=2)
22322243
return res + "\n"

chatlas/_tokens.py

Lines changed: 4 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22

33
import copy
44
import importlib.resources as resources
5-
import warnings
65
from threading import Lock
76
from typing import TYPE_CHECKING
87

@@ -47,12 +46,12 @@ def log_tokens(
4746
"model": model,
4847
"input": input_tokens,
4948
"output": output_tokens,
50-
"cost": compute_price(name, model, input_tokens, output_tokens),
49+
"cost": compute_cost(name, model, input_tokens, output_tokens),
5150
}
5251
else:
5352
self._tokens[name]["input"] += input_tokens
5453
self._tokens[name]["output"] += output_tokens
55-
price = compute_price(name, model, input_tokens, output_tokens)
54+
price = compute_cost(name, model, input_tokens, output_tokens)
5655
if price is not None:
5756
cost = self._tokens[name]["cost"]
5857
if cost is None:
@@ -122,24 +121,17 @@ def get_token_pricing(name: str, model: str) -> TokenPrice | None:
122121
-------
123122
TokenPrice | None
124123
"""
125-
result = next(
124+
return next(
126125
(
127126
item
128127
for item in pricing_list
129128
if item["provider"] == name and item["model"] == model
130129
),
131130
None,
132131
)
133-
if result is None:
134-
warnings.warn(
135-
f"Token pricing for the provider '{name}' and model '{model}' you selected is not available. "
136-
"Please check the provider's documentation."
137-
)
138-
139-
return result
140132

141133

142-
def compute_price(
134+
def compute_cost(
143135
name: str, model: str, input_tokens: int, output_tokens: int
144136
) -> float | None:
145137
"""

tests/test_chat.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -310,7 +310,7 @@ def test_get_cost():
310310
"Expected `options` to be one of 'all' or 'last', not 'bad_option'"
311311
),
312312
):
313-
chat.get_cost(options="bad_option")
313+
chat.get_cost(options="bad_option") # type: ignore
314314

315315
# Checking that these have the right form vs. the actual calculation because the price may change
316316
cost = chat.get_cost(options="all")

tests/test_tokens.py

Lines changed: 5 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
from chatlas import ChatAnthropic, ChatGoogle, ChatOpenAI, Turn
33
from chatlas._openai import OpenAIAzureProvider, OpenAIProvider
44
from chatlas._tokens import (
5-
compute_price,
5+
compute_cost,
66
get_token_pricing,
77
token_usage,
88
tokens_log,
@@ -59,29 +59,22 @@ def test_token_count_method():
5959
def test_get_token_prices():
6060
chat = ChatOpenAI(model="o1-mini")
6161
pricing = get_token_pricing(chat.provider.name, chat.provider.model)
62+
assert pricing is not None
6263
assert pricing["provider"] == "OpenAI"
6364
assert pricing["model"] == "o1-mini"
6465
assert isinstance(pricing["cached_input"], float)
6566
assert isinstance(pricing["input"], float)
6667
assert isinstance(pricing["output"], float)
6768

68-
with pytest.warns(
69-
match="Token pricing for the provider 'OpenAI' and model 'ABCD' you selected is not available. "
70-
"Please check the provider's documentation."
71-
):
72-
chat = ChatOpenAI(model="ABCD")
73-
pricing = get_token_pricing(chat.provider.name, chat.provider.model)
74-
assert pricing is None
7569

76-
77-
def test_compute_price():
70+
def test_compute_cost():
7871
chat = ChatOpenAI(model="o1-mini")
79-
price = compute_price(chat.provider.name, chat.provider.model, 10, 50)
72+
price = compute_cost(chat.provider.name, chat.provider.model, 10, 50)
8073
assert isinstance(price, float)
8174
assert price > 0
8275

8376
chat = ChatOpenAI(model="ABCD")
84-
price = compute_price(chat.provider.name, chat.provider.model, 10, 50)
77+
price = compute_cost(chat.provider.name, chat.provider.model, 10, 50)
8578
assert price is None
8679

8780

0 commit comments

Comments
 (0)