Skip to main content

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 value
  • placeholder: 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__(): Raises TypeError to prevent iteration

Security Considerations

  • The actual value is stored in memory and can be accessed via the value attribute
  • 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


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

printsafe-0.1.0.tar.gz (14.1 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

printsafe-0.1.0-py3-none-any.whl (5.1 kB view details)

Uploaded Python 3

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

Hashes for printsafe-0.1.0.tar.gz
Algorithm Hash digest
SHA256 e8d52a8681805e098be0069c92473b4deebcc25b56ae6a282d070603ef820c3c
MD5 48a0df5e2f6425eba29143850033454a
BLAKE2b-256 de57a241000e022b004378304f39840802e7e1b31e3f158cf8e4d0a24ef85942

See more details on using hashes here.

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

Hashes for printsafe-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 18563e105b85f93b071704861f9a7885adf90d394fbd18e15046a9267c573238
MD5 fac9604820a9af7f4384075dec26e1d0
BLAKE2b-256 ecfa747828d56fa24d2c378df36c7564adb0ec29e236ef42dbfc8418ed642c9b

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page