Skip to content

Commit e908cb2

Browse files
committed
Add Anthropic caching example and version history
1 parent 8b6bf01 commit e908cb2

9 files changed

Lines changed: 661 additions & 4 deletions

File tree

CHANGELOG.md

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,19 @@
33
Notable changes for token-throttle releases. Each major version's breaking
44
changes and upgrade steps are recorded in its entry below.
55

6+
## Unreleased
7+
8+
- Adds a runnable Anthropic Messages example with independent RPM, ITPM, and
9+
OTPM buckets; server-side pre-flight token counting; prompt-cache prewarming;
10+
cache-aware input refunds; observed-p99 output reservations; raw rate-limit
11+
header logging; and conservative cleanup on every response/error path.
12+
- Clarifies in the README that the high major-version sequence reflects strict
13+
semver during rapid beta development, rather than implying ten generations
14+
of product maturity.
15+
- Restores the missing v2.0.0-v4.0.0 history from the archived migration guide
16+
and adds explicit upgrade actions to the terse v5.0.0-v8.0.0 entries, so the
17+
changelog's major-version migration claim is complete and auditable.
18+
619
## 10.0.0 - 2026-07-07
720

821
- **Breaking:** this library no longer carries pre-v9 upgrade tooling. The
@@ -337,6 +350,10 @@ changes and upgrade steps are recorded in its entry below.
337350
- Raises dependency floors to `pydantic>=2.12.0` and `tiktoken>=0.10.0`.
338351
- Retains Python 3.14 support after fixing the conformance harness behavior.
339352
- Refreshes README, migration, custom-backend, and public docstring coverage.
353+
- **Upgrade:** drain Redis-backed in-flight reservations before deploying v8,
354+
route refunds through the limiter lifetime that issued each reservation,
355+
replace implicit loguru routing with explicit stdlib/application callbacks,
356+
and update the dependency floors above.
340357

341358
## v7.0.1 - 2026-05-22
342359

@@ -353,12 +370,18 @@ changes and upgrade steps are recorded in its entry below.
353370
- Closed the critical exception-propagation contracts.
354371
- Added conformance AST guards for cancellation-composition reachability.
355372
- Skipped Redis-specific critical-propagation tests when the Redis optional dependency is absent.
373+
- **Upgrade:** custom backends and callers must allow lifecycle-critical
374+
exceptions to propagate raw instead of wrapping them in ordinary cleanup
375+
errors; rerun the appropriate backend conformance helper before deployment.
356376

357377
## v6.0.0 - 2026-05-20
358378

359379
- Breaking: user callbacks now propagate `MemoryError` and `RecursionError`
360380
instead of treating them as ordinary warning-only failures.
361381
- Updated callback critical-exception handling and release metadata.
382+
- **Upgrade:** audit callbacks and tests that assumed every callback failure was
383+
warning-only; ordinary exceptions remain best-effort, but process-health
384+
exceptions must escape.
362385

363386
## v5.2.2 - 2026-05-20
364387

@@ -400,3 +423,55 @@ changes and upgrade steps are recorded in its entry below.
400423
- Documented deferred production items around proxy validation, topology,
401424
capacity sizing, OpenAI counter accuracy, tenant isolation, and Redis Cluster
402425
redesign.
426+
- **Upgrade:** third-party backends must implement the complete protocol surface
427+
and pass `conformance_test_for(...)`, `run_conformance_test_for(...)`, or
428+
`sync_conformance_test_for(...)` before moving from v4.
429+
430+
## v4.0.0 - 2026-05-16
431+
432+
- **Breaking:** `CapacityReservation` became an opaque handle backed by the
433+
issuing limiter's internal snapshot. Copying or mutating a returned DTO no
434+
longer redirects or resizes a refund; pass actual usage to the refund API.
435+
- **Breaking:** `AcquireRefundFailedError` stopped inheriting from
436+
`asyncio.CancelledError` and instead exposes the original interruption through
437+
`.interrupted_by`. Catch `AcquireRefundFailedError` directly when recovering
438+
a delivered reservation whose automatic cleanup failed.
439+
- **Breaking:** Redis builders reject Redis Cluster, and public DTO/key inputs
440+
gained stricter exact-type, character, and length validation.
441+
- **Upgrade:** v3 and v4 reservation/refund authority is intentionally not
442+
wire-compatible. Stop new v3 work, drain or expire in-flight reservations,
443+
then deploy v4; do not run a mixed fleet on one Redis prefix. Canary with an
444+
isolated prefix if a drained cutover is not possible.
445+
446+
## v3.0.0 - 2026-05-15
447+
448+
- **Breaking:** Redis acquires now write a durable acquire marker, and refunds
449+
must consume that marker before capacity is credited. This prevents forged or
450+
pre-v3 reservations from fabricating capacity.
451+
- Duplicate refunds continue to fail closed with `DuplicateRefundError`; an
452+
unprovable reservation fails with `UnknownReservationError` and is not
453+
credited.
454+
- **Upgrade:** drain or refund every v2 reservation before deploying v3. Mixed
455+
v2/v3 Redis fleets on the same prefix are unsupported because v2 does not
456+
write the markers v3 requires.
457+
458+
## v2.1.0 - 2026-05-15
459+
460+
- Adds optional `max_reservation_lifetime_seconds`; Redis backends derive a
461+
bounded default from their TTL configuration when it is omitted.
462+
- Hardens durable refund outcomes, capacity-setting reconciliation, close
463+
transactions, cardinality accounting, DTO trust boundaries, and Redis key
464+
prefix invariants without a further public migration break.
465+
466+
## v2.0.0 - 2026-05-13
467+
468+
- **Breaking:** Redis builders require an explicit tenant `key_prefix`, legacy
469+
v1.4 reservations without modern limiter identity are rejected, and bucket
470+
state gains expiration plus refund de-duplication.
471+
- Configuration, DTO, key-segment, callback, close, and in-process cardinality
472+
boundaries became fail-closed; OpenAI factory callback defaults are merged by
473+
slot rather than replacing an entire caller bundle.
474+
- **Upgrade:** preflight configuration against the stricter shapes, drain v1.4
475+
reservations, assign stable per-tenant Redis prefixes, clean up legacy Redis
476+
bucket keys only after the old fleet is stopped, and audit DTO subclasses and
477+
partial callback construction before deploying v2.

README.md

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ pip install "token-throttle>=10.0.0,<11.0.0" # Any provider +
2222

2323
Requires Python 3.12+. The Redis backend requires Redis 6.2+, standalone or Sentinel only — not Redis Cluster or client-side sharding (see [docs/operations.md](docs/operations.md)).
2424

25-
token-throttle follows strict semver: breaking changes ship only as major versions, and several recent majors were correctness hardening found through fault-injection testing rather than churn. Pin an exact major range (as shown above) and review the [CHANGELOG](CHANGELOG.md) before upgrading — each major's breaking changes and upgrade steps are recorded there. Public constants and type aliases: [docs/api.md](docs/api.md).
25+
token-throttle is beta and follows strict semver. The recent major-version sequence reflects rapid beta development, with each incompatible API or correctness change released as a major. Pin an exact major range (as shown above) and review the [CHANGELOG](CHANGELOG.md) before upgrading — each major's breaking changes and upgrade steps are recorded there. Public constants and type aliases: [docs/api.md](docs/api.md).
2626

2727
## Quickstart
2828

@@ -146,6 +146,10 @@ Unrecognized model names raise a clear error directing you to pass a custom
146146
billing, so compare reserved tokens with actual usage periodically. Full
147147
contract: [docs/configuration.md](docs/configuration.md#usage-counters).
148148

149+
### Anthropic (worked example)
150+
151+
Anthropic's Messages API enforces RPM, input tokens/minute (ITPM), and output tokens/minute (OTPM) independently; most current models exclude cache reads from ITPM, while OTPM counts actual output rather than `max_tokens`. The runnable [Anthropic prompt-caching example](examples/anthropic_prompt_caching.py) uses the Anthropic SDK's server-side token count, reserves ITPM and an observed output p99 separately, pre-warms a cache entry, refunds from the response's actual usage, and logs the two remaining-token headers. Supply the real limits from Claude Console (Settings > Limits) or the Rate Limits API instead of copying a tier table. Provider contracts: [rate limits](https://platform.claude.com/docs/en/api/rate-limits), [token counting](https://platform.claude.com/docs/en/build-with-claude/token-counting), and [prompt caching](https://platform.claude.com/docs/en/build-with-claude/prompt-caching).
152+
149153
### Any provider (manual usage)
150154

151155
The manual acquire -> refund pattern that `reserve()` wraps, with explicit error handling:

examples/__init__.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
"""Runnable provider examples for token-throttle."""

0 commit comments

Comments
 (0)