pdum.aws
AWS utils
Installation
Install using pip:
pip install habemus-papadum-aws
Or using uv:
uv pip install habemus-papadum-aws
Usage
Nothing here hardcodes a profile, region, or account. Credentials come from
boto3's own resolution, so you pick an account the standard way:
AWS_PROFILE=my-account python -m my_script
Identity
from pdum import aws
print(aws.whoami()["Account"])
ssm = aws.client("ssm")
Secrets
A SecretStore is a namespaced view of SSM Parameter Store. Reads check the
environment first, so a shell export or test fixture overrides without touching
AWS. The prefix is required — a shared default would let unrelated projects
collide in one namespace.
from pdum.aws.secrets import SecretStore
store = SecretStore("/myapp/")
store.put("STRIPE_KEY", "sk_live_...")
store.get("STRIPE_KEY", required=True)
store.names()
Service quotas
A fresh AWS account can launch almost nothing — typically 5 vCPUs of standard on-demand EC2 and zero of every accelerator family. These helpers report on that and request increases, returning data rather than printing so callers own presentation.
from pdum.aws import quotas
for status in quotas.report(quotas.EC2_VCPU_TARGETS, region="us-east-1"):
print(status.target.label, status.current, status.state)
results = quotas.submit(quotas.EC2_VCPU_TARGETS, region="us-east-1")
submit is idempotent: quotas already satisfied, or already carrying an open
request, are skipped rather than resubmitted. It stops cleanly when the account
hits its undocumented cap of ~20 simultaneously open requests, so the workflow
is submit, wait for cases to be decided, submit again.
Command line
Installing the package provides pdum-aws. There is deliberately no --profile
flag — pick an account the standard way, so this behaves like every other AWS
tool on the box.
AWS_PROFILE=my-account pdum-aws whoami
Secrets
The prefix has no default. Pass --prefix or set PDUM_SSM_PREFIX once.
export PDUM_SSM_PREFIX=/myapp/
pdum-aws secrets list # names only
pdum-aws secrets list --long # type, version, last modified
pdum-aws secrets get API_KEY # value alone, safe to pipe
printf %s 'sk_live_...' | pdum-aws secrets set API_KEY -
pdum-aws secrets rm API_KEY
pdum-aws secrets import .secrets --dry-run
pdum-aws secrets export
set reads stdin when the value is omitted or given as -; prefer that, since
a value passed as an argument lands in your shell history. import refuses to
push AWS bootstrap keys (AWS_ACCESS_KEY_ID, AWS_PROFILE, …) — storing the
credentials you need in order to reach the store would be circular.
Quotas
pdum-aws quotas status --region us-east-1 --region us-west-2
pdum-aws quotas history --region us-east-1 # what AWS decided
pdum-aws quotas request --region us-east-1 --dry-run
pdum-aws quotas request --region us-east-1
--region is repeatable; omit it to use whatever the environment resolves.
quotas targets prints the bundled EC2 plan as JSON so you can edit it and pass
it back with --targets:
pdum-aws quotas targets > my-targets.json
pdum-aws quotas request --targets my-targets.json
Do not infer a quota's value from its request status. AWS also raises limits on
young accounts automatically, independently of any request — quotas status
shows the applied value, which is the number that matters.
Embedding these commands in your own CLI
Each group is produced by a factory, so another application can mount the same
commands under its own name — carrying its own defaults, rendering through its
own console. That is how you give an app a secrets subcommand without asking
its users to type a prefix:
import typer
from rich.console import Console
from pdum.aws.cli import add_whoami, aws_errors, build_quotas_app, build_secrets_app
console = Console()
app = typer.Typer(help="acme — the whole product.", no_args_is_help=True)
add_whoami(app, console=console)
app.add_typer(
build_secrets_app(console=console, default_prefix="/acme/", envvar="ACME_SSM_PREFIX"),
name="secrets",
)
app.add_typer(
build_quotas_app(console=console, default_targets=ACME_TARGETS, default_regions=["us-east-1"]),
name="quotas",
)
def main() -> None:
with aws_errors(console):
app()
acme secrets list now works bare, and acme secrets --help shows
[default: /acme/] and [env var: ACME_SSM_PREFIX] rather than this library's.
The prefix resolves in order: --prefix, then the environment variable named by
envvar, then default_prefix, then an error. Pass a zero-argument callable as
default_prefix when the host reads it from a config file and wants that read
deferred to invocation, or expose_prefix_option=False to drop the flag and pin
the namespace.
build_quotas_app takes default_service, default_targets (a list or a
callable) and default_regions on the same terms, plus show_service_option /
show_targets_option to keep flags out of --help that a host's users have no
business changing. Both factories accept store_factory / default_targets
callables as the seam for host configuration — e.g.
store_factory=lambda prefix: SecretStore(prefix, region=cfg.region).
Two details worth knowing. aws_errors is the wrapper that turns an expired SSO
session into one readable line instead of a botocore traceback; wrap your entry
point in it to get the same treatment. And the groups keep their per-invocation
state in ctx.meta under namespaced keys rather than in ctx.obj, so mounting
them never disturbs what your own callback stores there — a host command can
reach both, via pdum.aws.cli.secrets.store_from(ctx) and ctx.obj.
Development
This project uses UV for dependency management.
Setup
# Install UV if you haven't already
curl -LsSf https://astral.sh/uv/install.sh | sh
# Clone the repository
git clone https://github.com/habemus-papadum/pdum_aws.git
cd pdum_aws
# Provision the entire toolchain (uv sync, pre-commit hooks)
./scripts/setup.sh
Important for Development:
./scripts/setup.shis idempotent—rerun it after pulling dependency changes- Use
uv sync --frozento ensure the lockfile is respected when installing Python deps
Running Tests
# Run all tests
uv run pytest
# Run a specific test file
uv run pytest tests/test_example.py
# Run a specific test function
uv run pytest tests/test_example.py::test_version
# Run tests with coverage
uv run pytest --cov=src/pdum/aws --cov-report=xml --cov-report=term
Code Quality
# Check code with ruff
uv run ruff check .
# Format code with ruff
uv run ruff format .
# Fix auto-fixable issues
uv run ruff check --fix .
Documentation
# Serve documentation locally (auto-reloads on changes)
uv run mkdocs serve
# Build documentation
uv run mkdocs build
# Test demo notebooks (if you have notebooks in docs/demos/)
./scripts/test_notebooks.sh
Important: After making any changes to demo notebooks, run ./scripts/test_notebooks.sh to verify they execute without errors.
Building
# Build Python
./scripts/build.sh
# Or build just the Python distribution artifacts
uv build
Publishing
# Build and publish to PyPI (requires credentials)
./scripts/publish.sh
Automation scripts
./scripts/setup.sh– bootstrap uv, pnpm, widget bundle, and pre-commit hooks./scripts/build.sh– reproduce the release build locally./scripts/pre-release.sh– run the full battery of quality checks./scripts/release.sh– orchestrate the release (creates tags, publishes to PyPI/GitHub)./scripts/test_notebooks.sh– execute demo notebooks (uses./scripts/nb.shunder the hood)
License
MIT License - see LICENSE file for details.
Metadata
Release files for habemus-papadum-aws 0.2.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 | |
|---|---|---|---|
| habemus_papadum_aws-0.2.0.tar.gz | 124.1 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| habemus_papadum_aws-0.2.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 153.4 kB
Release files / habemus_papadum_aws-0.2.0.tar.gz
| Download URL | habemus_papadum_aws-0.2.0.tar.gz |
|---|---|
| Size | 124.1 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
2723a5f97504afe40911ddcf16b00dc7005b2d9935e0c0efff16d32ea56c3ae8
|
|
BLAKE2b-256 checksum How to use checksums |
47ebfa48a593b06bc571e67d3156661eb125ac9a656b4015e23b98a2789ca8cc
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
Hatch/1.17.1 {"ci":null,"cpu":"arm64","distro":{"name":"macOS","version":"26.5.1"},"implementation":{"name":"CPython","version":"3.14.0"},"installer":{"name":"hatch","version":"1.17.1"},"openssl_version":"OpenSSL 3.6.2 7 Apr 2026","python":"3.14.0","system":{"name":"Darwin","release":"25.5.0"}} HTTPX2/2.9.1
|
Release files / habemus_papadum_aws-0.2.0-py3-none-any.whl
| Download URL | habemus_papadum_aws-0.2.0-py3-none-any.whl |
|---|---|
| Size | 29.3 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
4e66e9536ab2e60b2824203cbd639fffb995126fe5fa44a95e46d7ca51861cf8
|
|
BLAKE2b-256 checksum How to use checksums |
1915b695af5e97eab2299fad17cb28a8104314e35f90e052c4764d3bb65b0a0b
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
Hatch/1.17.1 {"ci":null,"cpu":"arm64","distro":{"name":"macOS","version":"26.5.1"},"implementation":{"name":"CPython","version":"3.14.0"},"installer":{"name":"hatch","version":"1.17.1"},"openssl_version":"OpenSSL 3.6.2 7 Apr 2026","python":"3.14.0","system":{"name":"Darwin","release":"25.5.0"}} HTTPX2/2.9.1
|