This document describes, step by step, how this repository evolved from a
plain FastAPI project into fastapi_payloadshield — a published, pluggable
encryption/decryption decorator package for FastAPI.
The repository began as a plain FastAPI project with a requirement:
Add base64 encryption/decryption to request/response payloads using a decorator, with no changes required at the route level — just add the decorator.
A first version implemented three simple decorators: encrypt_response,
decrypt_request, and crypto_middleware, hard-coded to base64.
To make adding new encryption types easy, the package introduced:
EncryptionHandler(ABC) withencode()/decode().- A handler registry (
register_handler,get_handler). - Decorator factories
PayloadShieldEnc(type),PayloadShieldDec(type),PayloadShield(type)accepting anencryption_typestring. - Backward-compatible aliases for the v1 decorator names.
- All
*.mddocs (exceptREADME.md) moved intodocument/. - License changed from MIT to Apache-2.0.
MANIFEST.in,publish.batch,publish.shadded for packaging/release.
The PyPI package name and Python import name went through several iterations before settling on a single consistent name:
| Stage | PyPI name | Python module |
|---|---|---|
| Initial | fastapi-base64-crypto |
fastapi_base64_crypto |
| Intermediate | fastapi-shield |
fastapi_shield |
| Final | fastapi-payloadshield |
fastapi_payloadshield |
Each rename required renaming the package directory, updating every import
across code/docs, updating setup.py/pyproject.toml, and reinstalling in
editable mode (pip install -e .) to clear stale .pth entries left by
previous names.
The decorator/init API was redesigned from scratch, with no backward compatibility:
- Removed entirely:
encrypt_response,decrypt_request,crypto_middleware, and the oldPayloadShieldEnc(type)/PayloadShieldDec(type)/PayloadShield(type)factory functions. - New decorator API:
PayloadShield.encrypt(type),PayloadShield.decrypt(type),PayloadShield.crypt(type)— static methods on aPayloadShieldclass. - New global key configuration:
PayloadShieldEnc.init({"Key": ..., "PrivateKey": ..., "PublicKey": ...}), called once at startup. Every handler pulls the keys it needs from this shared config at call time.PrivateKey/PublicKeyaccept either a file path or raw PEM content. - Handler signatures standardized to
encode(data, config)/decode(encoded_data, config)so every handler (built-in or custom) receives the same global config dict. - New built-in handlers:
fernet(symmetric),aes-gcm-256(symmetric, rewritten on top of thecryptographylibrary instead of pycryptodome), andrsa-hybrid(RSA-OAEP wrapping an AES-256-GCM payload key) — in addition to the originalbase64handler. - Added a pytest suite (
tests/) covering handler roundtrips, key configuration, and decorator behavior via FastAPI'sTestClient. - Consolidated
document/down toDEVELOPMENT.md,PUBLISHING_GUIDE.md, and this file — removed docs that only described the now-removed v1/v2 API surface to avoid duplicated/obsolete guidance.README.mdis the single source of truth for the current public API.
Build and release process (document/PUBLISHING_GUIDE.md):
- Clean
build/,dist/,*.egg-info/. pip install --upgrade build twinepython -m buildtwine check dist/*twine upload --config-file <pypirc-path> dist/*
A PyPI API token was at one point shared in plaintext (chat message and a local config file). Any token exposed this way should be treated as compromised and rotated immediately via the PyPI account's API token settings — tokens must never be committed to the repository.
- Package: PyPI name
fastapi_payloadshield, Python import namefastapi_payloadshield(consistent). - Public API:
PayloadShieldEnc.init(...)for configuration;PayloadShield.encrypt/decrypt/crypt(type)decorators. - Built-in handlers:
base64,fernet,aes-gcm-256,rsa-hybrid. - Fully pluggable via
register_handler(name, handler).