class SignatureManager
A class that manages digital signature images for documents, providing functionality to store, retrieve, and list signature files in a designated directory.
/tf/active/vicechatdev/document_auditor/src/security/signature_manager.py
6 - 141
moderate
Purpose
The SignatureManager class handles the lifecycle of digital signature images used in document signing workflows. It provides methods to add new signatures, retrieve existing signatures by signer name, and list all available signatures. The class automatically handles file naming conventions, directory creation, image format conversion, and provides fallback mechanisms for finding signatures with alternative naming patterns. It's designed to be used in document processing systems where digital signatures need to be applied to PDFs or other document formats.
Source Code
class SignatureManager:
"""Manages digital signatures for documents"""
def __init__(self, signatures_dir="signatures"):
"""
Initialize the signature manager
Args:
signatures_dir (str): Path to directory containing signature images
"""
self.logger = logging.getLogger(__name__)
self.signatures_dir = signatures_dir
# Ensure the signatures directory exists
if not os.path.isdir(self.signatures_dir):
os.makedirs(self.signatures_dir, exist_ok=True)
self.logger.info(f"Created signatures directory: {self.signatures_dir}")
def get_signature_path(self, name):
"""
Get the path to a signature image for a given name
Args:
name (str): Name of the person whose signature to retrieve
Returns:
str: Path to signature image if found, None otherwise
"""
# Convert the name to a filename (lowercase, spaces to underscores)
filename = name.lower().replace(" ", "_") + ".png"
signature_path = os.path.join(self.signatures_dir, filename)
if os.path.exists(signature_path):
self.logger.debug(f"Found signature for {name}: {signature_path}")
return signature_path
else:
self.logger.warning(f"No signature found for {name} (looked for {signature_path})")
# Try alternative filenames
alt_filenames = [
name.lower().replace(" ", "-") + ".png", # with hyphens
name.replace(" ", "") + ".png", # no spaces
"_".join(name.lower().split()) + ".png", # with underscores
name + ".png" # exact name
]
for alt_filename in alt_filenames:
alt_path = os.path.join(self.signatures_dir, alt_filename)
if os.path.exists(alt_path):
self.logger.info(f"Found signature with alternative name: {alt_path}")
return alt_path
return None
def add_signature(self, signer_name, signature_image_path):
"""
Add a signature image to the signatures directory
Args:
signer_name (str): Name of the signer
signature_image_path (str): Path to signature image
Returns:
str: Path to the saved signature image
"""
if not os.path.exists(signature_image_path):
raise FileNotFoundError(f"Signature image not found: {signature_image_path}")
# Normalize signer name for filename
normalized_name = self._normalize_name(signer_name)
# Determine file extension
ext = os.path.splitext(signature_image_path)[1].lower()
if not ext or ext not in ['.png', '.jpg', '.jpeg', '.gif']:
# Default to PNG if not a supported format
ext = '.png'
# Create destination path
dest_path = os.path.join(self.signatures_dir, f"{normalized_name}{ext}")
# Process the image - ensure it has transparency if PNG
try:
img = Image.open(signature_image_path)
# Convert to RGBA if PNG
if ext == '.png':
img = img.convert('RGBA')
# Save the processed image
img.save(dest_path)
self.logger.info(f"Added signature for {signer_name}: {dest_path}")
return dest_path
except Exception as e:
self.logger.error(f"Error processing signature image: {e}")
raise
def list_available_signatures(self):
"""
List all available signature files
Returns:
list: List of names with available signatures
"""
signatures = []
if not os.path.exists(self.signatures_dir):
return signatures
# Get all PNG files in the signatures directory
for filename in os.listdir(self.signatures_dir):
if filename.lower().endswith('.png'):
# Convert filename back to a name (remove extension, replace underscores with spaces)
name = os.path.splitext(filename)[0].replace("_", " ").title()
signatures.append(name)
return signatures
def _normalize_name(self, name):
"""
Normalize a name for filename use
Args:
name (str): Name to normalize
Returns:
str: Normalized name
"""
# Replace spaces with underscores and convert to lowercase
normalized = name.strip().replace(' ', '_').lower()
# Remove special characters
normalized = ''.join(c for c in normalized if c.isalnum() or c == '_')
return normalized
Parameters
| Name | Type | Default | Kind |
|---|---|---|---|
bases |
- | - |
Parameter Details
signatures_dir: Path to the directory where signature image files will be stored and retrieved. Defaults to 'signatures'. The directory will be created automatically if it doesn't exist. This should be a string representing either a relative or absolute path to the desired storage location.
Return Value
Instantiation returns a SignatureManager object that maintains state about the signatures directory and provides methods for signature management. Key method returns: get_signature_path() returns a string path to the signature file or None if not found; add_signature() returns the string path where the signature was saved; list_available_signatures() returns a list of strings representing available signer names; _normalize_name() returns a normalized string suitable for use as a filename.
Class Interface
Methods
__init__(self, signatures_dir='signatures')
Purpose: Initialize the SignatureManager with a directory for storing signature images
Parameters:
signatures_dir: Path to directory containing signature images, defaults to 'signatures'
Returns: None (constructor)
get_signature_path(self, name: str) -> str | None
Purpose: Retrieve the file path to a signature image for a given signer name, trying multiple naming conventions
Parameters:
name: Name of the person whose signature to retrieve
Returns: String path to the signature image file if found, None if no matching signature exists
add_signature(self, signer_name: str, signature_image_path: str) -> str
Purpose: Add a signature image to the signatures directory with proper naming and format conversion
Parameters:
signer_name: Name of the signer to associate with this signaturesignature_image_path: Path to the source signature image file to be added
Returns: String path to the saved signature image in the signatures directory
list_available_signatures(self) -> list
Purpose: List all available signature files in the signatures directory
Returns: List of strings representing names with available signatures (converted from filenames to readable names)
_normalize_name(self, name: str) -> str
Purpose: Normalize a person's name for use as a filename by converting to lowercase, replacing spaces with underscores, and removing special characters
Parameters:
name: Name to normalize
Returns: Normalized string suitable for use as a filename
Attributes
| Name | Type | Description | Scope |
|---|---|---|---|
logger |
logging.Logger | Logger instance for recording debug, info, warning, and error messages during signature operations | instance |
signatures_dir |
str | Path to the directory where signature image files are stored and retrieved | instance |
Dependencies
osloggingglobPIL
Required Imports
import os
import logging
import glob
from PIL import Image
Usage Example
import os
import logging
from PIL import Image
# Set up logging
logging.basicConfig(level=logging.INFO)
# Create a SignatureManager instance
sig_manager = SignatureManager(signatures_dir='./my_signatures')
# Add a new signature
try:
saved_path = sig_manager.add_signature('John Doe', '/path/to/john_signature.png')
print(f'Signature saved to: {saved_path}')
except FileNotFoundError as e:
print(f'Error: {e}')
# Retrieve a signature path
signature_path = sig_manager.get_signature_path('John Doe')
if signature_path:
print(f'Found signature at: {signature_path}')
else:
print('Signature not found')
# List all available signatures
available = sig_manager.list_available_signatures()
print(f'Available signatures: {available}')
Best Practices
- Always instantiate the SignatureManager with a dedicated directory path to avoid mixing signature files with other data
- Ensure the application has write permissions to the signatures directory before instantiation
- Use add_signature() to add new signatures rather than manually copying files to ensure proper format conversion and naming
- The class automatically creates the signatures directory if it doesn't exist, so no pre-setup is required
- Signature files are normalized to lowercase with underscores replacing spaces, but get_signature_path() handles multiple naming conventions automatically
- When adding signatures, supported image formats are PNG, JPG, JPEG, and GIF; PNG is recommended for transparency support
- The class uses logging extensively, so configure logging appropriately to capture debug, info, warning, and error messages
- get_signature_path() tries multiple filename variations automatically, making it resilient to different naming conventions
- The _normalize_name() method is private and should not be called directly by external code
Tags
Similar Components
AI-powered semantic similarity - components with related functionality:
-
function main_v30 60.1% similar
-
class SignatureGenerator 57.7% similar
-
class SignatureImage 55.9% similar
-
class SignatureImage_v1 55.9% similar
-
class DocumentProcessor 49.4% similar