FastAPI Payload Shield
Lightweight FastAPI decorators for automatic encryption/decryption of request and response payloads. Supports pluggable encryption handlers - easily add new encryption types like AES, Fernet, or custom algorithms!
🎯 Key Features
- 🔒 Flexible Encryption: Multiple encryption types (base64, AES, Fernet, custom)
- 🔓 Automatic Decryption: Decrypt incoming requests automatically
- 📝 JSON-Friendly: Works seamlessly with JSON requests and responses
- 🎯 Route-Agnostic: No changes needed to your existing route logic
- ⚡ Lightweight: Minimal dependencies and overhead
- 🚀 Easy Integration: Just add decorators to your routes
- 🧩 Pluggable: Create custom encryption handlers easily
Installation
From Local Development
cd FastAPIPS
pip install -e .
From PyPI (when published)
pip install fastapi_payloadshield
Quick Start
Basic Usage with Base64
from fastapi import FastAPI
from fastapi_payloadshield import PayloadShieldEnc, PayloadShieldDec, PayloadShield
app = FastAPI()
# Encrypt response only
@app.get("/api/data")
@PayloadShieldEnc("base64")
async def get_data():
return {"message": "hello", "data": "world"}
# Decrypt request only
@app.post("/api/process")
@PayloadShieldDec("base64")
async def process_data(data: dict):
return {"received": data, "status": "success"}
@app.post("/api/secure")
@PayloadShield("base64")
async def secure_endpoint(data: dict):
return {"processed": data}
Decorators
@PayloadShieldEnc(encryption_type)
Encrypts the response payload.
@app.get("/api/users")
@PayloadShieldEnc("base64")
async def get_users():
return [{"id": 1, "name": "Alice"}]
# Response: {"encrypted": "W3siaWQiOiAxLCAibmFtZSI6ICJBbGljZSJ9XQ=="}
@PayloadShieldDec(encryption_type)
Decrypts the request payload.
@app.post("/api/login")
@PayloadShieldDec("base64")
async def login(credentials: dict):
return {"status": "success"}
# Expects: {"encrypted": "base64_encoded_json"}
@PayloadShield(encryption_type)
Combined encryption and decryption
@app.post("/api/secure")
@PayloadShield("base64")
async def secure_endpoint(data: dict):
return {"processed": data}
# Expects: {"encrypted": "encrypted_data"}
# Returns: {"encrypted": "encrypted_data"}
Advanced Example: Multiple Encryption Types
from fastapi import FastAPI
from fastapi_payloadshield import PayloadShield, register_handler, EncryptionHandler
from cryptography.fernet import Fernet
import json
app = FastAPI()
# Create Fernet handler
class FernetHandler(EncryptionHandler):
def __init__(self, key):
self.cipher = Fernet(key)
def encode(self, data):
return self.cipher.encrypt(json.dumps(data).encode()).decode()
def decode(self, encoded_data):
return json.loads(self.cipher.decrypt(encoded_data.encode()))
# Register
key = Fernet.generate_key()
register_handler("fernet", FernetHandler(key))
# Use different encryption for different endpoints
@app.post("/api/public")
@PayloadShield("base64") # Light encryption
async def public_endpoint(data: dict):
return data
@app.post("/api/private")
@PayloadShield("fernet") # Strong encryption
async def private_endpoint(data: dict):
return data
How It Works
Request Decryption Flow
- Client sends:
{"encrypted": "encrypted_data"} @PayloadShieldDecdecorator intercepts- Decrypts using specified handler
- Route receives:
{"key": "value"}(normal dict)
Response Encryption Flow
- Route returns:
{"key": "value"} @PayloadShieldEncdecorator intercepts- Encrypts using specified handler
- Client receives:
{"encrypted": "encrypted_data"}
Testing
Run Example Application
python examples/example_app.py
Run Test Client
python examples/test_client.py
Manual Test with cURL
# Encrypt test data
echo '{"username":"admin"}' | base64
# eyJ1c2VybmFtZSI6ImFkbWluIn0=
# Send encrypted request
curl -X POST http://localhost:8000/api/login \
-H "Content-Type: application/json" \
-d '{"encrypted":"eyJ1c2VybmFtZSI6ImFkbWluIn0="}'
Testing with Python
import requests
import json
import base64
# Encode request
data = {"username": "admin", "password": "secret"}
json_str = json.dumps(data)
encrypted = base64.b64encode(json_str.encode()).decode()
# Send request
response = requests.post(
"http://localhost:8000/api/login",
json={"encrypted": encrypted}
)
# Decode response
encrypted_response = response.json()["encrypted"]
decrypted = json.loads(base64.b64decode(encrypted_response).decode())
print(decrypted)
# {'status': 'success', 'token': 'abc123'}
Creating Custom Encryption Handlers
See CUSTOM_HANDLERS.md for detailed guide on:
- Creating custom handlers
- Fernet encryption example
- AES encryption example
- Best practices
- Performance tips
- Security considerations
Backward Compatibility
Old decorator names still work:
from fastapi_payloadshield import encrypt_response, decrypt_request, crypto_middleware
# These are equivalent to:
# PayloadShieldEnc("base64")
# PayloadShieldDec("base64")
# PayloadShield("base64")
@app.get("/api/data")
@encrypt_response
async def get_data():
return {"data": "value"}
API Reference
Decorators
| Decorator | Purpose |
|---|---|
PayloadShieldEnc(type) |
Encrypt response |
PayloadShieldDec(type) |
Decrypt request |
PayloadShield(type) |
Both encrypt & decrypt |
Functions
| Function | Purpose |
|---|---|
register_handler(name, handler) |
Register custom encryption handler |
get_handler(name) |
Get handler by name |
EncryptionHandler |
Base class for handlers |
Built-in Handlers
| Handler | Type | Security | Use Case |
|---|---|---|---|
base64 |
Encoding | None | Obfuscation, development |
Error Handling
The decorators include built-in error handling:
# Invalid encrypted data
# Response: {"error": "Failed to decrypt request: ..."}
# Missing encryption handler
# Response: ValueError: Encryption handler 'xyz' not found. Available: base64, fernet
Performance Considerations
- Caching: Handler instances are cached
- Compression: Consider compressing before encryption for large payloads
- Async: All operations are async-friendly
Requirements
- Python 3.7+
- FastAPI 0.68+
- Starlette 0.19+
Files Included
fastapi_payloadshield/- Main package__init__.py- Exports decorators and handlerscrypto.py- Encryption handlersdecorators.py- FastAPI decorators
examples/- Working examplesexample_app.py- Full-featured demotest_client.py- Test/client script
README.md- This fileQUICKSTART.md- Quick start guideCUSTOM_HANDLERS.md- Creating custom handlersDEVELOPMENT.md- Development guide
License
Apache-2.0 - See LICENSE file for details
Contributing
Contributions welcome! Areas for contribution:
- New encryption handlers (AES, Fernet, etc.)
- Performance optimizations
- Documentation improvements
- Test coverage
- Examples
Support
- 📖 Full guide: README.md
- ⚡ Quick start: QUICKSTART.md
- 🧩 Custom handlers: CUSTOM_HANDLERS.md
- 🛠️ Development: DEVELOPMENT.md
Happy encrypting! 🔒
Why Payload Shield?
This package was designed with extensibility in mind. Unlike static encryption libraries, Payload Shield lets you:
- Mix and match encryption types in the same app
- Add new encryption types without touching core code
- Keep route logic clean and simple
- Support multiple security levels
Perfect for:
- Building multi-tier security APIs
- Migrating from one encryption to another
- Testing different encryption strategies
- Production systems requiring flexible crypto
Release files for fastapi-payloadshield 1.0.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 | |
|---|---|---|---|
| fastapi_payloadshield-1.0.0.tar.gz | 39.7 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| fastapi_payloadshield-1.0.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 50.9 kB
Release files / fastapi_payloadshield-1.0.0.tar.gz
| Download URL | fastapi_payloadshield-1.0.0.tar.gz |
|---|---|
| Size | 39.7 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
4561e90fef8aa77ccef77139e5345729d723ca630e92b51581ad4d95f6af90ee
|
|
BLAKE2b-256 checksum How to use checksums |
a75de87d4c5209c167ec421fccb63743eb7d3f91cf27906405f46451466a3d5c
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Release files / fastapi_payloadshield-1.0.0-py3-none-any.whl
| Download URL | fastapi_payloadshield-1.0.0-py3-none-any.whl |
|---|---|
| Size | 11.2 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
8e4324f900755d066bdabd3f82c57b5c0e447c01061c513c143df47f99316108
|
|
BLAKE2b-256 checksum How to use checksums |
6814723dbff72cc470ff3080595edd251322b5be02abae5e3c3d0ca174b86d31
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|