Python library to keep secrets out of logs
Project description
printsafe
A Python library that prevents accidental exposure of sensitive data in logs, debug output, and string representations.
Overview
printsafe provides a Secret class that wraps sensitive values (passwords, API keys, tokens, etc.) and prevents them from being accidentally exposed through:
- String representation (
str(),print()) - Debug output (
repr()) - Logging statements
- Iteration (prevents character-by-character exposure)
The wrapped value remains fully accessible when explicitly requested, but is protected from accidental disclosure.
Installation
pip install printsafe
Quick Start
from printsafe import Secret
# Wrap a sensitive value
api_key = Secret("sk-1234567890abcdef")
# Safe operations - won't expose the secret
print(api_key) # Output: [REDACTED]
print(f"API Key: {api_key}") # Output: API Key: [REDACTED]
str(api_key) # Returns: "[REDACTED]"
repr(api_key) # Returns: "[REDACTED]"
# Access the actual value when needed
actual_key = api_key.value # Returns: "sk-1234567890abcdef"
Usage Examples
Basic Usage
from printsafe import Secret
# Create a secret with default placeholder
password = Secret("my_super_secret_password")
print(password) # [REDACTED]
# Create a secret with custom placeholder
token = Secret("abc123xyz", placeholder="<HIDDEN>")
print(token) # <HIDDEN>
Working with Different Data Types
# String secrets
api_key = Secret("sk-1234567890")
# Numeric secrets
secret_number = Secret(42)
print(secret_number) # [REDACTED]
print(secret_number.value) # 42
# Dictionary secrets
config = Secret({"database_url": "postgresql://user:pass@host/db"})
print(config) # [REDACTED]
print(config.value["database_url"]) # Access nested values
Method Delegation
The Secret class delegates method calls to the wrapped value:
secret_text = Secret("hello world")
# These methods are delegated to the wrapped string
print(secret_text.upper()) # Raises AttributeError or returns delegated result
print(secret_text.value.upper()) # "HELLO WORLD" - safe explicit access
Callable Secrets
If the wrapped value is callable, the Secret can be called directly:
def secret_function(x):
return x * 2
secret_func = Secret(secret_function)
result = secret_func(5) # Calls the wrapped function, returns 10
Comparison and Hashing
secret1 = Secret("password123")
secret2 = Secret("password123")
secret3 = Secret("different")
# Equality comparison
print(secret1 == secret2) # True
print(secret1 == secret3) # False
print(secret1 == "password123") # True
# Can be used in sets and as dict keys
secrets = {secret1, secret2} # Set with one unique secret
secret_dict = {secret1: "user1"}
Prevented Operations
secret = Secret("sensitive")
# These operations are blocked to prevent exposure:
try:
for char in secret: # Iteration blocked
print(char)
except TypeError as e:
print(e) # 'Secret' object is not iterable
API Reference
Secret(value, placeholder="[REDACTED]")
Parameters
value: The sensitive value to wrap (any type)placeholder(str, optional): Text to display instead of the actual value. Defaults to"[REDACTED]"
Attributes
value: Access the wrapped sensitive valueplaceholder: The placeholder text used for string representation
Methods
__str__(): Returns the placeholder string__repr__(): Returns the placeholder string__eq__(other): Compare with another Secret or value__hash__(): Returns hash of the wrapped value__call__(*args, **kwargs): Call the wrapped value if it's callable__getattr__(name): Delegate attribute access to wrapped value
Blocked Operations
__iter__(): RaisesTypeErrorto prevent iteration
Security Considerations
- The actual value is stored in memory and can be accessed via the
valueattribute - This library protects against accidental exposure, not malicious access
- Memory dumps or debugging tools may still reveal the sensitive data
- Consider additional security measures for highly sensitive applications
Contributing
Contributions are welcome! Please feel free to submit a Pull Request.
License
This project is licensed under the MIT License - see the LICENSE file for details.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file printsafe-0.1.0.tar.gz.
File metadata
- Download URL: printsafe-0.1.0.tar.gz
- Upload date:
- Size: 14.1 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.6.2
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
e8d52a8681805e098be0069c92473b4deebcc25b56ae6a282d070603ef820c3c
|
|
| MD5 |
48a0df5e2f6425eba29143850033454a
|
|
| BLAKE2b-256 |
de57a241000e022b004378304f39840802e7e1b31e3f158cf8e4d0a24ef85942
|
File details
Details for the file printsafe-0.1.0-py3-none-any.whl.
File metadata
- Download URL: printsafe-0.1.0-py3-none-any.whl
- Upload date:
- Size: 5.1 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.6.2
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
18563e105b85f93b071704861f9a7885adf90d394fbd18e15046a9267c573238
|
|
| MD5 |
fac9604820a9af7f4384075dec26e1d0
|
|
| BLAKE2b-256 |
ecfa747828d56fa24d2c378df36c7564adb0ec29e236ef42dbfc8418ed642c9b
|