Skip to content

Misc utilities

Small stateless helpers from the base SDK (no extra). Each solves a recurring pain so you don't rewrite it.

UTC dates — utcnow / to_utc

utcnow() returns a timezone-aware "now" in UTC (never the naive datetime.utcnow(), a classic bug source); to_utc(value) normalizes any datetime to UTC (assuming UTC when the input is naive).

from datetime import datetime

from tempest_fastapi_sdk import to_utc, utcnow

created_at: datetime = utcnow()                  # 2026-06-07T19:00:00+00:00
normalized: datetime = to_utc(some_naive_dt)     # becomes aware/UTC

Filter/extend a dict — modify_dict

Drops keys and merges new ones in a single pass, returning a new dict (it never mutates the original):

from tempest_fastapi_sdk import modify_dict

payload = {"id": 1, "password": "x", "name": "Ana"}
safe = modify_dict(payload, exclude=["password"], include={"role": "user"})
# {"id": 1, "name": "Ana", "role": "user"}

Client IP — get_client_ip

Resolves the IP from the request, optionally trusting one edge-set header (proxy/LB). Without trusted_header it uses only the direct peer — don't blindly trust a world-exposed X-Forwarded-For.

from fastapi import Request

from tempest_fastapi_sdk import get_client_ip


@router.get("/whoami")
async def whoami(request: Request) -> dict[str, str]:
    ip: str = get_client_ip(request, trusted_header="x-real-ip")
    return {"ip": ip}   # "unknown" when neither the header nor the peer exists

Opaque tokens — generate_opaque_token / verify_opaque_token

For API keys, reset/invite tokens, etc.: generate a (plaintext, hash) pair, show the plaintext once to the user, and persist only the hash (SHA-256). Verification is constant-time.

from tempest_fastapi_sdk import (
    generate_opaque_token,
    hash_opaque_token,
    verify_opaque_token,
)

plaintext, token_hash = generate_opaque_token()   # show plaintext once; store token_hash
# ... later, when the token comes back:
ok: bool = verify_opaque_token(submitted, token_hash)
# hash_opaque_token(x) to re-hash on demand

Why opaque, not JWT

Opaque tokens are revocable (just delete the hash) and carry no readable claims. Use them for long-lived secrets (API keys); use JWT for short-lived stateless sessions.

Recap

  • utcnow() / to_utc() — always timezone-aware UTC.
  • modify_dict(data, exclude=, include=) — filter + extend without mutating.
  • get_client_ip(request, trusted_header=) — client IP, with opt-in trusted header.
  • generate_opaque_token() / verify_opaque_token() — hash-and-store secrets, constant-time verify.