SPB Git

spb/ultra-sharp-agent-skills Public

Ultra-Sharp Agent Skills — a research-first skill-authoring system + 72 production-ready skills for AI agents.

Python 100%
4.0 KB · 108 lines markdown
Rendered Raw Blame History
1<!--2Author: Simon-Pierre Boucher3Contact: contact@spboucher.ai4-->56# Patterns — Managing Configuration78## Contents9- Typed settings with pydantic-settings10- .env.example catalog format11- Secret manager integration12- Config-value-driven behavior (no env-name branches)13- Startup validation test14- Gotchas1516## Typed settings with pydantic-settings1718```python19# pip install pydantic-settings20from pydantic import Field, PostgresDsn, SecretStr21from pydantic_settings import BaseSettings2223class Settings(BaseSettings):24    # Required in every environment — no default means boot fails without it.25    database_url: PostgresDsn26    secret_key: SecretStr                      # SecretStr never repr()s its value2728    # Safe dev defaults; prod overrides via env.29    log_level: str = "DEBUG"30    payments_sandbox: bool = True31    request_timeout_s: float = Field(10.0, gt=0)  # upstream p99 ~3s; 10s bounds hangs3233    model_config = {"env_file": ".env", "frozen": True}3435settings = Settings()   # raises with every missing/invalid key named, at import36```3738Node equivalent: `znv`/`zod` — parse `process.env` through a schema once, export the frozen result.3940## .env.example catalog format4142```bash43# --- Required -----------------------------------------------------------44DATABASE_URL=postgresql://app:app@localhost:5432/app   # primary database45SECRET_KEY=change-me                                   # session signing; generate: openssl rand -hex 324647# --- Optional (defaults shown) ------------------------------------------48LOG_LEVEL=DEBUG                # DEBUG|INFO|WARN|ERROR; prod: INFO49PAYMENTS_SANDBOX=true          # false only in production50REQUEST_TIMEOUT_S=1051```5253Copy to `.env` for local dev; `.env` stays in `.gitignore`.5455## Secret manager integration5657Injected-env pattern (works with AWS/GCP/Vault/Doppler — the app stays ignorant):5859```bash60# deploy layer resolves secrets into env; app just reads env61aws secretsmanager get-secret-value --secret-id prod/app --query SecretString ...62# or: doppler run -- python -m app     /     vault agent + envconsul63```6465Direct-fetch escape hatch (only when the platform can't inject):6667```python68def load_secret(name: str) -> str:69    import boto370    return boto3.client("secretsmanager").get_secret_value(SecretId=name)["SecretString"]71```7273Rules either way: fetched at boot, held in memory only, never written to disk or logs.7475## Config-value-driven behavior7677```python78# ❌ environment-name branching — untestable matrix, staging drift79if os.environ.get("ENV") == "staging":80    client = SandboxPayments()8182# ✅ capability flag — set PAYMENTS_SANDBOX=true wherever sandbox is wanted83client = SandboxPayments() if settings.payments_sandbox else LivePayments()84```8586## Startup validation test8788```python89import subprocess, sys9091def test_boot_fails_without_database_url(monkeypatch):92    env = {k: v for k, v in os.environ.items() if k != "DATABASE_URL"}93    proc = subprocess.run([sys.executable, "-c", "import app.settings"],94                          env=env, capture_output=True, text=True)95    assert proc.returncode != 096    assert "database_url" in proc.stderr.lower()   # the key is NAMED97```9899Secret hygiene scan in CI: `gitleaks detect --no-banner` (fails the build on committed secrets).100101## Gotchas102- Env vars are strings: `DEBUG=False` is truthy as a raw string — always parse through the schema, never `bool(os.environ.get(...))`.103- `.env` loaded in production shadows real env injection and hides misconfiguration; enable env_file only outside prod or ensure real env wins (pydantic-settings: real env takes precedence by default).104- Default-then-override dicts (`config.update(prod_config)`) make the effective value untraceable; one flat schema, one source.105- Printing the settings object at boot is a classic secret leak — use `SecretStr`/redacted repr.106- Rotating a secret must not require a rebuild — if it does, the secret is baked into the image (wrong layer).107- Feature-flag creep: a "flag" older than one quarter is config wearing a costume — promote it or delete it.108