litellm-cost 0.1.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,35 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 AKN Runtime
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
22
+
23
+ ---
24
+
25
+ Attribution / Derivation notice:
26
+
27
+ This package is a decomposition of the cost-estimation logic found in
28
+ LiteLLM (https://github.com/BerriAI/litellm), which is distributed under the
29
+ MIT License. The pricing data schema and the token-to-cost math are derived
30
+ from LiteLLM's `model_prices_and_context_window.json` and
31
+ `litellm.cost_calculator` / `litellm.utils` modules, stripped of runtime
32
+ dependencies (network I/O, provider routing, logging, telemetry).
33
+
34
+ Upstream reference at extraction time: LiteLLM v1.85.1.
35
+ This package is versioned independently of upstream.
@@ -0,0 +1,7 @@
1
+ include LICENSE
2
+ include README.md
3
+ include provenance/model_prices.json
4
+ recursive-include docs *.md
5
+ recursive-include scripts *.py
6
+ recursive-exclude tests *
7
+ global-exclude __pycache__ *.pyc .coverage
@@ -0,0 +1,213 @@
1
+ Metadata-Version: 2.4
2
+ Name: litellm-cost
3
+ Version: 0.1.0
4
+ Summary: Standalone LLM cost estimation: model pricing data + token cost math, extracted from LiteLLM with zero litellm dependency.
5
+ Author-email: AKN Runtime <akn-runtime@users.noreply.github.com>
6
+ License: MIT
7
+ Project-URL: Homepage, https://github.com/akn-runtime/litellm-cost
8
+ Project-URL: Documentation, https://github.com/akn-runtime/litellm-cost#readme
9
+ Project-URL: Source, https://github.com/akn-runtime/litellm-cost
10
+ Project-URL: Upstream, https://github.com/BerriAI/litellm
11
+ Keywords: llm,cost,token,pricing,estimation,litellm
12
+ Classifier: Development Status :: 4 - Beta
13
+ Classifier: Intended Audience :: Developers
14
+ Classifier: License :: OSI Approved :: MIT License
15
+ Classifier: Operating System :: OS Independent
16
+ Classifier: Programming Language :: Python :: 3
17
+ Classifier: Programming Language :: Python :: 3.9
18
+ Classifier: Programming Language :: Python :: 3.10
19
+ Classifier: Programming Language :: Python :: 3.11
20
+ Classifier: Programming Language :: Python :: 3.12
21
+ Classifier: Topic :: Software Development :: Libraries
22
+ Classifier: Topic :: System :: Systems Administration
23
+ Requires-Python: >=3.9
24
+ Description-Content-Type: text/markdown
25
+ License-File: LICENSE
26
+ Provides-Extra: tiktoken
27
+ Requires-Dist: tiktoken>=0.7; extra == "tiktoken"
28
+ Provides-Extra: dev
29
+ Requires-Dist: pytest>=8.0; extra == "dev"
30
+ Requires-Dist: pytest-cov>=5.0; extra == "dev"
31
+ Dynamic: license-file
32
+
33
+ # litellm-cost
34
+
35
+ **Standalone LLM cost estimation: model pricing data + token cost math, with zero `litellm` dependency.**
36
+
37
+ [![PyPI - Version](https://img.shields.io/pypi/v/litellm-cost.svg)](https://pypi.org/project/litellm-cost/)
38
+ [![PyPI - Python Version](https://img.shields.io/pypi/pyversions/litellm-cost.svg)](https://pypi.org/project/litellm-cost/)
39
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
40
+ [![Tests](https://img.shields.io/badge/tests-114%20passing-brightgreen.svg)]()
41
+
42
+ ---
43
+
44
+ ## Why this package exists
45
+
46
+ [LiteLLM](https://github.com/BerriAI/litellm) is a 100+ provider LLM gateway — but its cost
47
+ estimation logic is trapped inside a 9,700-line god-module (`litellm/utils.py`) and paid for
48
+ with a heavy dependency bill (pydantic, httpx, openai, jinja2, …). Two design choices make it
49
+ painful to reuse in isolation:
50
+
51
+ 1. **Import-time network fetch** — `import litellm` pulls the pricing JSON from GitHub by
52
+ default, which fails or blocks in offline / air-gapped environments and adds a supply-chain
53
+ surface.
54
+ 2. **Dependency bloat** — the cost path only needs a data dictionary and arithmetic, yet
55
+ installing `litellm` drags in the full gateway stack.
56
+
57
+ `litellm-cost` extracts exactly the reusable core — the pricing data dictionary and the
58
+ token-to-cost math — into a **zero-dependency** package that:
59
+
60
+ - never touches the network on import (or at all, unless you explicitly ask it to refresh),
61
+ - exposes a small, typed, documented API,
62
+ - ships an embedded pricing snapshot with its own `data_version` for traceability,
63
+ - keeps the upstream O(1) case-insensitive model lookup and CJK-aware token heuristics.
64
+
65
+ ## Installation
66
+
67
+ ```bash
68
+ pip install litellm-cost
69
+ ```
70
+
71
+ Optional extras:
72
+
73
+ ```bash
74
+ pip install "litellm-cost[tiktoken]" # tiktoken accelerator for token estimation
75
+ pip install "litellm-cost[dev]" # pytest + pytest-cov for development
76
+ ```
77
+
78
+ Python **3.9 – 3.12** supported. No third-party dependencies in the core package.
79
+
80
+ ## Quick start
81
+
82
+ ### Estimate the cost of a call
83
+
84
+ ```python
85
+ from litellm_cost import get_cost
86
+
87
+ # gpt-4o: $2.5e-06 / input token, $1e-05 / output token
88
+ cost = get_cost("gpt-4o", input_tokens=1250, output_tokens=350)
89
+ print(f"${cost:.6f}") # $0.006625
90
+
91
+ # provider-prefixed model keys work as in LiteLLM
92
+ cost = get_cost("groq/llama-3.1-8b-instant", input_tokens=1000, output_tokens=500)
93
+
94
+ # cached tokens are billed at the model's cache-read price
95
+ # (defaults to 50% of the input price when the data has no explicit value)
96
+ cost = get_cost("gpt-4o", input_tokens=1000, cache_read_tokens=900)
97
+
98
+ # or pass an OpenAI-style usage block directly
99
+ cost = get_cost("gpt-4o", usage={"prompt_tokens": 100, "completion_tokens": 50})
100
+ ```
101
+
102
+ ### Estimate tokens (no tokenizer dependency)
103
+
104
+ ```python
105
+ from litellm_cost import estimate_tokens
106
+
107
+ estimate_tokens("Hello, world!") # heuristic, CJK-aware
108
+ estimate_tokens("你好世界,这是一个测试。") # CJK text handled correctly
109
+ estimate_tokens([{"role": "user", "content": "Hi"}]) # OpenAI-style messages
110
+
111
+ # opt-in tiktoken accelerator (silently falls back to the heuristic
112
+ # when tiktoken is not installed)
113
+ estimate_tokens("Hello, world!", use_tiktoken=True, model="gpt-4o")
114
+ ```
115
+
116
+ ### Query pricing data
117
+
118
+ ```python
119
+ from litellm_cost import get_pricing, list_providers, data_version
120
+
121
+ info = get_pricing("gpt-4o")
122
+ print(info["input_cost_per_token"]) # 2.5e-06
123
+ print(info["max_input_tokens"]) # 128000
124
+
125
+ providers = list_providers() # full 100+ provider roster
126
+ print(data_version()) # e.g. "2025.06.17.1"
127
+ ```
128
+
129
+ ### Handle errors explicitly
130
+
131
+ ```python
132
+ from litellm_cost import LitellmCostError, UnknownModel, MissingPricing, ContextWindowExceededError
133
+
134
+ try:
135
+ get_cost("not-a-real-model", input_tokens=10)
136
+ except UnknownModel as exc:
137
+ print(exc) # unknown model: 'not-a-real-model'. It is not present in the embedded pricing data...
138
+
139
+ try:
140
+ get_cost("gpt-4o", input_tokens=10**9, check_context_window=True)
141
+ except ContextWindowExceededError:
142
+ pass # opt-in: off by default, cost estimation should not fail on hypothetical usage
143
+ ```
144
+
145
+ ### Keep pricing data fresh
146
+
147
+ The embedded snapshot is versioned and traceable. To update it from LiteLLM's upstream
148
+ `model_prices_and_context_window.json` (stdlib only, no third-party dependencies):
149
+
150
+ ```bash
151
+ python -m litellm_cost.refresh --check # dry run: report without writing
152
+ python -m litellm_cost.refresh # fetch, merge, bump data_version
153
+ ```
154
+
155
+ Or programmatically:
156
+
157
+ ```python
158
+ from litellm_cost.refresh import refresh_pricing_data
159
+
160
+ summary = refresh_pricing_data()
161
+ print(summary) # {"data_version": ..., "models": ..., "providers": ..., "written": True}
162
+ ```
163
+
164
+ The refresh pipeline inherits LiteLLM's own supply-chain guards: the fetched payload must be a
165
+ non-empty JSON object, and the refresh is always an explicit, opt-in action — never an import
166
+ side effect.
167
+
168
+ ## API overview
169
+
170
+ | Function | Purpose |
171
+ |---|---|
172
+ | `get_cost(model, ...)` | Compute the USD cost of a call from token counts |
173
+ | `estimate_tokens(source, ...)` | Estimate tokens for text or OpenAI-style messages |
174
+ | `get_pricing(model)` | Query the pricing-info dict for a model (defensive copy) |
175
+ | `list_providers()` | Sorted list of supported providers (100+) |
176
+ | `cost_per_token(model)` | `(input_cost_per_token, output_cost_per_token)` tuple |
177
+ | `data_version()` | Version string of the embedded pricing data |
178
+
179
+ Full signatures, parameter tables, error semantics and examples:
180
+ **[docs/API.md](docs/API.md)**.
181
+
182
+ ## Relationship to LiteLLM
183
+
184
+ This package is a **decomposition** of the cost-estimation logic found in LiteLLM
185
+ (`litellm.cost_calculator`, `litellm.utils`, `litellm_core_utils.token_counter`, and the
186
+ `model_prices_and_context_window.json` data dictionary), stripped of runtime dependencies
187
+ (network I/O, provider routing, logging, telemetry). The extraction boundary review covers
188
+ LiteLLM **v1.85.1**; the package is versioned independently of upstream.
189
+
190
+ What is *not* copied: the router, the proxy server, provider request adapters, the
191
+ logging/telemetry stack, streaming processors, and the import-time network fetch.
192
+
193
+ ## License
194
+
195
+ MIT — see [LICENSE](LICENSE). The LICENSE retains the upstream attribution notice: the pricing
196
+ data schema and token-to-cost math are derived from LiteLLM (MIT), and the embedded pricing
197
+ JSON is upstream community-maintained data with its source URL recorded in the bundle.
198
+
199
+ ## Development
200
+
201
+ ```bash
202
+ git clone https://github.com/akn-runtime/litellm-cost
203
+ cd litellm-cost
204
+ pip install -e ".[dev]"
205
+ pytest
206
+ ```
207
+
208
+ To rebuild the distribution artifacts:
209
+
210
+ ```bash
211
+ pip install build
212
+ python -m build # produces sdist + wheel in dist/
213
+ ```
@@ -0,0 +1,181 @@
1
+ # litellm-cost
2
+
3
+ **Standalone LLM cost estimation: model pricing data + token cost math, with zero `litellm` dependency.**
4
+
5
+ [![PyPI - Version](https://img.shields.io/pypi/v/litellm-cost.svg)](https://pypi.org/project/litellm-cost/)
6
+ [![PyPI - Python Version](https://img.shields.io/pypi/pyversions/litellm-cost.svg)](https://pypi.org/project/litellm-cost/)
7
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
8
+ [![Tests](https://img.shields.io/badge/tests-114%20passing-brightgreen.svg)]()
9
+
10
+ ---
11
+
12
+ ## Why this package exists
13
+
14
+ [LiteLLM](https://github.com/BerriAI/litellm) is a 100+ provider LLM gateway — but its cost
15
+ estimation logic is trapped inside a 9,700-line god-module (`litellm/utils.py`) and paid for
16
+ with a heavy dependency bill (pydantic, httpx, openai, jinja2, …). Two design choices make it
17
+ painful to reuse in isolation:
18
+
19
+ 1. **Import-time network fetch** — `import litellm` pulls the pricing JSON from GitHub by
20
+ default, which fails or blocks in offline / air-gapped environments and adds a supply-chain
21
+ surface.
22
+ 2. **Dependency bloat** — the cost path only needs a data dictionary and arithmetic, yet
23
+ installing `litellm` drags in the full gateway stack.
24
+
25
+ `litellm-cost` extracts exactly the reusable core — the pricing data dictionary and the
26
+ token-to-cost math — into a **zero-dependency** package that:
27
+
28
+ - never touches the network on import (or at all, unless you explicitly ask it to refresh),
29
+ - exposes a small, typed, documented API,
30
+ - ships an embedded pricing snapshot with its own `data_version` for traceability,
31
+ - keeps the upstream O(1) case-insensitive model lookup and CJK-aware token heuristics.
32
+
33
+ ## Installation
34
+
35
+ ```bash
36
+ pip install litellm-cost
37
+ ```
38
+
39
+ Optional extras:
40
+
41
+ ```bash
42
+ pip install "litellm-cost[tiktoken]" # tiktoken accelerator for token estimation
43
+ pip install "litellm-cost[dev]" # pytest + pytest-cov for development
44
+ ```
45
+
46
+ Python **3.9 – 3.12** supported. No third-party dependencies in the core package.
47
+
48
+ ## Quick start
49
+
50
+ ### Estimate the cost of a call
51
+
52
+ ```python
53
+ from litellm_cost import get_cost
54
+
55
+ # gpt-4o: $2.5e-06 / input token, $1e-05 / output token
56
+ cost = get_cost("gpt-4o", input_tokens=1250, output_tokens=350)
57
+ print(f"${cost:.6f}") # $0.006625
58
+
59
+ # provider-prefixed model keys work as in LiteLLM
60
+ cost = get_cost("groq/llama-3.1-8b-instant", input_tokens=1000, output_tokens=500)
61
+
62
+ # cached tokens are billed at the model's cache-read price
63
+ # (defaults to 50% of the input price when the data has no explicit value)
64
+ cost = get_cost("gpt-4o", input_tokens=1000, cache_read_tokens=900)
65
+
66
+ # or pass an OpenAI-style usage block directly
67
+ cost = get_cost("gpt-4o", usage={"prompt_tokens": 100, "completion_tokens": 50})
68
+ ```
69
+
70
+ ### Estimate tokens (no tokenizer dependency)
71
+
72
+ ```python
73
+ from litellm_cost import estimate_tokens
74
+
75
+ estimate_tokens("Hello, world!") # heuristic, CJK-aware
76
+ estimate_tokens("你好世界,这是一个测试。") # CJK text handled correctly
77
+ estimate_tokens([{"role": "user", "content": "Hi"}]) # OpenAI-style messages
78
+
79
+ # opt-in tiktoken accelerator (silently falls back to the heuristic
80
+ # when tiktoken is not installed)
81
+ estimate_tokens("Hello, world!", use_tiktoken=True, model="gpt-4o")
82
+ ```
83
+
84
+ ### Query pricing data
85
+
86
+ ```python
87
+ from litellm_cost import get_pricing, list_providers, data_version
88
+
89
+ info = get_pricing("gpt-4o")
90
+ print(info["input_cost_per_token"]) # 2.5e-06
91
+ print(info["max_input_tokens"]) # 128000
92
+
93
+ providers = list_providers() # full 100+ provider roster
94
+ print(data_version()) # e.g. "2025.06.17.1"
95
+ ```
96
+
97
+ ### Handle errors explicitly
98
+
99
+ ```python
100
+ from litellm_cost import LitellmCostError, UnknownModel, MissingPricing, ContextWindowExceededError
101
+
102
+ try:
103
+ get_cost("not-a-real-model", input_tokens=10)
104
+ except UnknownModel as exc:
105
+ print(exc) # unknown model: 'not-a-real-model'. It is not present in the embedded pricing data...
106
+
107
+ try:
108
+ get_cost("gpt-4o", input_tokens=10**9, check_context_window=True)
109
+ except ContextWindowExceededError:
110
+ pass # opt-in: off by default, cost estimation should not fail on hypothetical usage
111
+ ```
112
+
113
+ ### Keep pricing data fresh
114
+
115
+ The embedded snapshot is versioned and traceable. To update it from LiteLLM's upstream
116
+ `model_prices_and_context_window.json` (stdlib only, no third-party dependencies):
117
+
118
+ ```bash
119
+ python -m litellm_cost.refresh --check # dry run: report without writing
120
+ python -m litellm_cost.refresh # fetch, merge, bump data_version
121
+ ```
122
+
123
+ Or programmatically:
124
+
125
+ ```python
126
+ from litellm_cost.refresh import refresh_pricing_data
127
+
128
+ summary = refresh_pricing_data()
129
+ print(summary) # {"data_version": ..., "models": ..., "providers": ..., "written": True}
130
+ ```
131
+
132
+ The refresh pipeline inherits LiteLLM's own supply-chain guards: the fetched payload must be a
133
+ non-empty JSON object, and the refresh is always an explicit, opt-in action — never an import
134
+ side effect.
135
+
136
+ ## API overview
137
+
138
+ | Function | Purpose |
139
+ |---|---|
140
+ | `get_cost(model, ...)` | Compute the USD cost of a call from token counts |
141
+ | `estimate_tokens(source, ...)` | Estimate tokens for text or OpenAI-style messages |
142
+ | `get_pricing(model)` | Query the pricing-info dict for a model (defensive copy) |
143
+ | `list_providers()` | Sorted list of supported providers (100+) |
144
+ | `cost_per_token(model)` | `(input_cost_per_token, output_cost_per_token)` tuple |
145
+ | `data_version()` | Version string of the embedded pricing data |
146
+
147
+ Full signatures, parameter tables, error semantics and examples:
148
+ **[docs/API.md](docs/API.md)**.
149
+
150
+ ## Relationship to LiteLLM
151
+
152
+ This package is a **decomposition** of the cost-estimation logic found in LiteLLM
153
+ (`litellm.cost_calculator`, `litellm.utils`, `litellm_core_utils.token_counter`, and the
154
+ `model_prices_and_context_window.json` data dictionary), stripped of runtime dependencies
155
+ (network I/O, provider routing, logging, telemetry). The extraction boundary review covers
156
+ LiteLLM **v1.85.1**; the package is versioned independently of upstream.
157
+
158
+ What is *not* copied: the router, the proxy server, provider request adapters, the
159
+ logging/telemetry stack, streaming processors, and the import-time network fetch.
160
+
161
+ ## License
162
+
163
+ MIT — see [LICENSE](LICENSE). The LICENSE retains the upstream attribution notice: the pricing
164
+ data schema and token-to-cost math are derived from LiteLLM (MIT), and the embedded pricing
165
+ JSON is upstream community-maintained data with its source URL recorded in the bundle.
166
+
167
+ ## Development
168
+
169
+ ```bash
170
+ git clone https://github.com/akn-runtime/litellm-cost
171
+ cd litellm-cost
172
+ pip install -e ".[dev]"
173
+ pytest
174
+ ```
175
+
176
+ To rebuild the distribution artifacts:
177
+
178
+ ```bash
179
+ pip install build
180
+ python -m build # produces sdist + wheel in dist/
181
+ ```