Skip to content

Commit 90040d6

Browse files
nickwinderclaude
andcommitted
refactor(types): extract ExtractionCredits to dedicated module
The extraction-credits accounting shape (cost + remainingCredits) will surface on every future endpoint billed against the extraction-credits bucket, not just /extraction/parse. Factor it out of types/parse.py into its own module so other endpoints can import it without pulling in the whole parse type tree. Also clarify ParseBounds: document that (x, y) is the top-left corner and that bounds share a coordinate space with the page dimensions in ParsePageRef. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
1 parent 9a3cca2 commit 90040d6

4 files changed

Lines changed: 39 additions & 16 deletions

File tree

src/nutrient_dws/__init__.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
process_file_input,
2020
validate_file_input,
2121
)
22+
from nutrient_dws.types.extraction_credits import ExtractionCredits
2223
from nutrient_dws.types.parse import (
2324
FormulaElement,
2425
HandwritingElement,
@@ -42,6 +43,7 @@
4243
__all__ = [
4344
"APIError",
4445
"AuthenticationError",
46+
"ExtractionCredits",
4547
"FileInput",
4648
"FormulaElement",
4749
"HandwritingElement",
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
"""Shared types for the DWS **extraction credits** billing bucket.
2+
3+
Extraction credits are billed separately from the processor API credits
4+
consumed by `/build`, `/sign`, OCR, etc. The types in this module are
5+
intentionally endpoint-agnostic so they can be reused by any future
6+
endpoint that surfaces extraction-credit accounting in its response.
7+
"""
8+
9+
from typing import TypedDict
10+
11+
12+
class ExtractionCredits(TypedDict, total=False):
13+
"""Credit accounting for one request against the extraction-credits bucket.
14+
15+
`cost` is the number of **extraction credits** debited by the request
16+
(NOT processor API credits). `remainingCredits` is the post-debit
17+
balance in the same bucket.
18+
"""
19+
20+
cost: float
21+
remainingCredits: float

src/nutrient_dws/types/parse.py

Lines changed: 15 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@
1414

1515
from typing_extensions import TypedDict
1616

17+
from nutrient_dws.types.extraction_credits import ExtractionCredits
18+
1719
# ---- Request types --------------------------------------------------------
1820

1921
ParseMode = Literal["text", "structure", "understand", "agentic"]
@@ -58,7 +60,14 @@ class ParseInstructions(TypedDict, total=False):
5860

5961

6062
class ParseBounds(TypedDict):
61-
"""Axis-aligned bounding box, in the page's coordinate space."""
63+
"""Axis-aligned bounding box on the page.
64+
65+
`(x, y)` is the **top-left corner** of the box. The page's coordinate
66+
origin is the top-left, with `x` increasing to the right and `y`
67+
increasing downward. Units are pixels in the same canvas described by
68+
`ParsePageRef.width` and `ParsePageRef.height` (i.e. element bounds and
69+
the page dimensions share one coordinate space).
70+
"""
6271

6372
x: float
6473
y: float
@@ -285,26 +294,18 @@ class ParseConfiguration(TypedDict, total=False):
285294
outputFormat: ParseOutputFormat
286295

287296

288-
class ParseExtractionCredits(TypedDict, total=False):
289-
"""Credit accounting for this request.
290-
291-
`cost` is in **extraction credits** (NOT processor API credits) and
292-
`remainingCredits` is the remaining balance in the same bucket.
293-
"""
294-
295-
cost: float
296-
remainingCredits: float
297-
298-
299297
class ParseUsage(TypedDict, total=False):
300298
"""Wraps the extraction-credit accounting under its wire key.
301299
302300
The server uses the snake_case key `data_extraction_credits` here even
303301
though every other field in the response is camelCase; the TypedDict
304-
mirrors the wire format verbatim.
302+
mirrors the wire format verbatim. The inner `ExtractionCredits` type
303+
lives in `nutrient_dws.types.extraction_credits` because the same
304+
credit-accounting shape will surface on future endpoints that bill
305+
against the extraction-credits bucket.
305306
"""
306307

307-
data_extraction_credits: ParseExtractionCredits
308+
data_extraction_credits: ExtractionCredits
308309

309310

310311
class ParseFailingPath(TypedDict, total=False):

tests/unit/test_parse.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,7 @@
11
"""Unit tests for `NutrientClient.parse()`.
22
33
These tests stub `send_request` so they exercise the request-shape and
4-
response-handling logic of `parse()` without making a real HTTP call. The
5-
live smoke check is `examples/src/smoke_parse.py`.
4+
response-handling logic of `parse()` without making a real HTTP call.
65
"""
76

87
import json

0 commit comments

Comments
 (0)