metergraph-core 0.2.29__tar.gz → 0.2.30__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.
- {metergraph_core-0.2.29/src/metergraph_core.egg-info → metergraph_core-0.2.30}/PKG-INFO +1 -1
- {metergraph_core-0.2.29 → metergraph_core-0.2.30}/pyproject.toml +1 -1
- {metergraph_core-0.2.29 → metergraph_core-0.2.30}/src/metergraph_core/billing.py +55 -16
- {metergraph_core-0.2.29 → metergraph_core-0.2.30/src/metergraph_core.egg-info}/PKG-INFO +1 -1
- {metergraph_core-0.2.29 → metergraph_core-0.2.30}/MANIFEST.in +0 -0
- {metergraph_core-0.2.29 → metergraph_core-0.2.30}/README.md +0 -0
- {metergraph_core-0.2.29 → metergraph_core-0.2.30}/setup.cfg +0 -0
- {metergraph_core-0.2.29 → metergraph_core-0.2.30}/src/metergraph_core/__init__.py +0 -0
- {metergraph_core-0.2.29 → metergraph_core-0.2.30}/src/metergraph_core/catalog.py +0 -0
- {metergraph_core-0.2.29 → metergraph_core-0.2.30}/src/metergraph_core/data/prices.yaml +0 -0
- {metergraph_core-0.2.29 → metergraph_core-0.2.30}/src/metergraph_core/loader.py +0 -0
- {metergraph_core-0.2.29 → metergraph_core-0.2.30}/src/metergraph_core/retrieval.py +0 -0
- {metergraph_core-0.2.29 → metergraph_core-0.2.30}/src/metergraph_core.egg-info/SOURCES.txt +0 -0
- {metergraph_core-0.2.29 → metergraph_core-0.2.30}/src/metergraph_core.egg-info/dependency_links.txt +0 -0
- {metergraph_core-0.2.29 → metergraph_core-0.2.30}/src/metergraph_core.egg-info/requires.txt +0 -0
- {metergraph_core-0.2.29 → metergraph_core-0.2.30}/src/metergraph_core.egg-info/top_level.txt +0 -0
|
@@ -6,11 +6,49 @@ from typing import Any, Mapping
|
|
|
6
6
|
|
|
7
7
|
from .catalog import CostResult
|
|
8
8
|
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
9
|
+
@dataclass(frozen=True, slots=True)
|
|
10
|
+
class _QualifiedSource:
|
|
11
|
+
"""A gateway whose reported amount this module will bill from.
|
|
12
|
+
|
|
13
|
+
Three things have to line up before an amount is believed, because the field
|
|
14
|
+
carrying one is open: a customer's own client can write to it.
|
|
15
|
+
|
|
16
|
+
* The **gateway**, so an amount is attributed to a system we have checked.
|
|
17
|
+
* The **endpoint**, because a gateway prices its endpoints differently and a
|
|
18
|
+
figure is only interpretable alongside the one that produced it.
|
|
19
|
+
* The **source**, naming the field the amount was read from, so a row cannot
|
|
20
|
+
qualify by claiming a gateway name alone.
|
|
21
|
+
|
|
22
|
+
A gateway absent from this table is not distrusted so much as unverified:
|
|
23
|
+
its amount is still recorded, and the catalog still prices the call, so the
|
|
24
|
+
two can be compared before it is added here.
|
|
25
|
+
"""
|
|
26
|
+
|
|
27
|
+
gateway: str
|
|
28
|
+
endpoints: frozenset[str]
|
|
29
|
+
cost_source: str
|
|
30
|
+
upstream_cost_source: str | None = None
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
# Each entry reconciles against the providers' own published rates, including
|
|
34
|
+
# the per-request and per-query charges a token rate cannot express. Portkey was
|
|
35
|
+
# checked across a 46,241-call export: its figure matches published rates for
|
|
36
|
+
# Anthropic, xAI and Perplexity to the cent, and for OpenAI once the per-search
|
|
37
|
+
# charge is counted -- 20,590 of 20,590 rows, exactly.
|
|
38
|
+
_QUALIFIED_SOURCES = (
|
|
39
|
+
_QualifiedSource(
|
|
40
|
+
gateway="openrouter",
|
|
41
|
+
endpoints=frozenset({"chat.completions"}),
|
|
42
|
+
cost_source="openrouter.usage.cost",
|
|
43
|
+
upstream_cost_source=(
|
|
44
|
+
"openrouter.usage.cost_details.upstream_inference_cost"
|
|
45
|
+
),
|
|
46
|
+
),
|
|
47
|
+
_QualifiedSource(
|
|
48
|
+
gateway="portkey",
|
|
49
|
+
endpoints=frozenset({"chat.completions", "responses"}),
|
|
50
|
+
cost_source="portkey.cost",
|
|
51
|
+
),
|
|
14
52
|
)
|
|
15
53
|
|
|
16
54
|
|
|
@@ -82,11 +120,12 @@ def normalize_gateway_evidence(row: Mapping[str, Any]) -> GatewayBillingEvidence
|
|
|
82
120
|
)
|
|
83
121
|
|
|
84
122
|
|
|
85
|
-
def
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
and evidence.endpoint
|
|
89
|
-
|
|
123
|
+
def _qualified_source(evidence: GatewayBillingEvidence) -> _QualifiedSource | None:
|
|
124
|
+
"""The entry this row's gateway and endpoint match, if any."""
|
|
125
|
+
for source in _QUALIFIED_SOURCES:
|
|
126
|
+
if evidence.gateway == source.gateway and evidence.endpoint in source.endpoints:
|
|
127
|
+
return source
|
|
128
|
+
return None
|
|
90
129
|
|
|
91
130
|
|
|
92
131
|
def resolve_billing(
|
|
@@ -95,18 +134,18 @@ def resolve_billing(
|
|
|
95
134
|
) -> BillingDecision:
|
|
96
135
|
"""Select effective cost without combining independent reported amounts."""
|
|
97
136
|
|
|
98
|
-
|
|
137
|
+
qualified = _qualified_source(evidence)
|
|
99
138
|
reported_cost = (
|
|
100
139
|
evidence.reported_cost_usd
|
|
101
|
-
if
|
|
102
|
-
and evidence.reported_cost_source ==
|
|
140
|
+
if qualified is not None
|
|
141
|
+
and evidence.reported_cost_source == qualified.cost_source
|
|
103
142
|
else None
|
|
104
143
|
)
|
|
105
144
|
upstream_cost = (
|
|
106
145
|
evidence.reported_upstream_cost_usd
|
|
107
|
-
if
|
|
108
|
-
and
|
|
109
|
-
==
|
|
146
|
+
if qualified is not None
|
|
147
|
+
and qualified.upstream_cost_source is not None
|
|
148
|
+
and evidence.reported_upstream_cost_source == qualified.upstream_cost_source
|
|
110
149
|
else None
|
|
111
150
|
)
|
|
112
151
|
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{metergraph_core-0.2.29 → metergraph_core-0.2.30}/src/metergraph_core.egg-info/dependency_links.txt
RENAMED
|
File without changes
|
|
File without changes
|
{metergraph_core-0.2.29 → metergraph_core-0.2.30}/src/metergraph_core.egg-info/top_level.txt
RENAMED
|
File without changes
|