bedrockstack
Low-level Python ergonomics for AWS Bedrock + Anthropic Claude. Three primitives every team building on Bedrock ends up rewriting from scratch:
RetryPolicy— Bedrock-aware backoff that knows the difference between aThrottlingException(retry), aModelNotReadyException(wait longer), and aValidationException(never retry).Ledger— thread-safe cost tracking with scope tags, grouped totals, and Anthropic-on-Bedrock pricing baked in (override perLedger(prices=...)).wrap_stream()— normalize the streaming-error parity gap betweenAnthropicBedrockand the native Anthropic client into a single exception hierarchy.
This is the layer above boto3.client('bedrock-runtime'), not a replacement. Sibling library: bedrockcache for prompt-caching audits.
Install
pip install bedrockstack
Zero runtime dependencies. Works alongside whatever Bedrock client you already use (boto3, AnthropicBedrock, LiteLLM, Strands).
Retries
import boto3
from bedrockstack import bedrock_default
bedrock = boto3.client("bedrock-runtime", region_name="us-east-1")
policy = bedrock_default() # 6 attempts, 0.5s..30s exponential w/ jitter
response = policy.call(
lambda: bedrock.converse(modelId="anthropic.claude-sonnet-4-5-v1:0", ...)
)
What it does and doesn't retry:
| Retries | Never retries |
|---|---|
| ThrottlingException | ValidationException |
| ServiceUnavailableException | AccessDeniedException |
| InternalServerException | ResourceNotFoundException |
| ModelNotReadyException (with longer initial delay) | InvalidRequestException |
| ModelTimeoutException | ModelErrorException |
| ModelStreamErrorException | (anything else not in the retryable list) |
| ServiceQuotaExceededException | |
| Connection / read timeouts (matched by class name) |
Cost ledger
from bedrockstack import Ledger, Usage
led = Ledger()
with led.scope(user_id="abc", feature="rag"):
led.record(
model="anthropic.claude-sonnet-4-5-v1:0",
usage=Usage(input_tokens=10_000, output_tokens=2_000,
cache_read_input_tokens=8_000),
)
print(led.dollars(user_id="abc")) # 0.027
print(led.dollars(feature="rag")) # 0.027
print(led.totals(group_by="model")) # {'anthropic.claude-sonnet-4-5-v1:0': 0.027}
Inference-profile model IDs (us.anthropic.claude-...) and LiteLLM-style prefixes (bedrock/anthropic.claude-...) are normalized automatically.
To override prices when AWS rebases:
from bedrockstack import Ledger, ModelPrice
led = Ledger(prices={
"anthropic.claude-sonnet-4-5-v1:0": ModelPrice(0.0025, 0.0125, 0.00025, 0.003125),
})
Streaming-error normalization
from anthropic import AnthropicBedrock
from bedrockstack import wrap_stream, StreamOverloadedError, StreamRateLimitError
client = AnthropicBedrock()
stream = client.messages.create(model="anthropic.claude-sonnet-4-5-v1:0",
stream=True, messages=[...])
try:
for event in wrap_stream(stream):
...
except StreamOverloadedError:
# 529 mid-stream — back off long
...
except StreamRateLimitError:
# 429 mid-stream — back off short
...
The same wrap_stream() works against the native Anthropic client and AnthropicBedrock. You handle one set of exceptions instead of two.
What it explicitly is not
- Not an agent framework. Use Strands or pydantic-ai for that.
- Not a router. LiteLLM exists.
- Not a prompt-caching auditor — that's bedrockcache.
- Bedrock + Anthropic-only. No OpenAI / Vertex / Azure surface.
Sibling libraries
Three independent libraries that compose around Anthropic-on-Bedrock:
- bedrockcache — static auditor for prompt caching.
- bedrockstack (this) — retry policy, cost ledger, streaming-error normalization.
- ragvitals — 5-dim drift detection for the RAG pipelines these models live inside.
Roadmap
- v0.2:
ToolRunnerwith AnthropicBedrock parity (matches the native client'smessages.tool_runner). - v0.3:
BedrockClientwrapper that bundles retry + ledger + streaming around a boto3 client. - v0.4: region failover for inference-profile model IDs.
- v0.5: SageMaker Async Inference helper.
Develop
pip install -e ".[dev]"
pytest -v
License
MIT
Metadata
Release files for bedrockstack 0.1.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | |
|---|---|---|---|---|
| bedrockstack-0.1.0.tar.gz | 11.5 kB | Without provenance | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| bedrockstack-0.1.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 22.4 kB
Release files / bedrockstack-0.1.0.tar.gz
| Download URL | bedrockstack-0.1.0.tar.gz |
|---|---|
| Size | 11.5 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
c76c48d4c8d177f5dcd10cb7d1ca546c02e5e1b0da6bef9af8f0786883972f2c
|
|
BLAKE2b-256 checksum How to use checksums |
b87be8979b3c60fd57b1d354a0d23aa0e7618bd7af3daef507f136a0020b9d32
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.14.4
|
Release files / bedrockstack-0.1.0-py3-none-any.whl
| Download URL | bedrockstack-0.1.0-py3-none-any.whl |
|---|---|
| Size | 10.9 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
82101ed852f590553b200cffa232a1ac388961cff06e7a606e54c6295ec5cc94
|
|
BLAKE2b-256 checksum How to use checksums |
970cfd0694bd9140760381c95bc42a792c8a3d9c27a093365c7c0310fade49ce
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.14.4
|
Security for bedrockstack 0.1.0
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.