How to Create a Self-Destructing File Timer in Python
Sometimes you need a file, like a session token, temporary configuration, or sensitive data, to exist for only a limited time before being automatically deleted.
This guide demonstrates how to build a robust file monitor that watches a specific file and deletes it after a configurable expiration time.
Basic Implementation
We use pathlib for modern file handling and configparser for external configuration.
Configuration File
Create a config.ini file to control the deletion timing:
[Security]
delete_after_minutes = 5
Monitor Script
import time
import configparser
from pathlib import Path
def monitor_and_delete(target_file: str, config_file: str) -> None:
"""
Monitor a file and delete it after the configured expiry time.
Args:
target_file: Path to the file to monitor
config_file: Path to the configuration file
"""
file_path = Path(target_file)
config = configparser.ConfigParser()
config.read(config_file)
# Get expiry time with fallback default
minutes = config.getint("Security", "delete_after_minutes", fallback=1)
limit_seconds = minutes * 60
start_time = time.time()
print(f"Monitoring: {file_path}")
print(f"Expiry: {minutes} minute(s)")
while True:
# Exit if file was manually deleted
if not file_path.exists():
print("File no longer exists. Exiting monitor.")
break
elapsed = time.time() - start_time
remaining = limit_seconds - elapsed
# Check if time has expired
if remaining <= 0:
try:
file_path.unlink()
print(f"File '{target_file}' deleted after {minutes} minute(s).")
except PermissionError:
print("Error: Permission denied. File may be in use.")
except OSError as e:
print(f"Error deleting file: {e}")
break
# Sleep to prevent CPU waste
time.sleep(5)
if __name__ == "__main__":
# Create a test file
test_file = Path("secret.txt")
test_file.write_text("Top Secret Data")
monitor_and_delete("secret.txt", "config.ini")
Output:
Monitoring: secret.txt
Expiry: 1 minute(s)
File 'secret.txt' deleted after 1 minute(s).
Enhanced Version with Logging and Callbacks
For production use, add logging and optional callbacks:
import time
import configparser
import logging
from pathlib import Path
from typing import Callable, Optional
from datetime import datetime, timedelta
logging.basicConfig(
level=logging.INFO,
format="%(asctime)s - %(levelname)s - %(message)s"
)
logger = logging.getLogger(__name__)
class SelfDestructingFile:
"""Monitor a file and delete it after a specified duration."""
def __init__(
self,
target_file: str,
minutes: int = 5,
on_delete: Optional[Callable[[Path], None]] = None,
check_interval: int = 5
):
self.file_path = Path(target_file)
self.duration = timedelta(minutes=minutes)
self.on_delete = on_delete
self.check_interval = check_interval
self.start_time: Optional[datetime] = None
def start_monitoring(self) -> bool:
"""
Start monitoring the file.
Returns:
True if file was deleted, False if file disappeared
"""
if not self.file_path.exists():
logger.error(f"File not found: {self.file_path}")
return False
self.start_time = datetime.now()
expiry_time = self.start_time + self.duration
logger.info(f"Monitoring: {self.file_path}")
logger.info(f"Scheduled deletion: {expiry_time.strftime('%H:%M:%S')}")
while True:
if not self.file_path.exists():
logger.warning("File was removed externally. Stopping monitor.")
return False
if datetime.now() >= expiry_time:
return self._delete_file()
time.sleep(self.check_interval)
def _delete_file(self) -> bool:
"""Attempt to delete the file."""
try:
self.file_path.unlink()
logger.info(f"Successfully deleted: {self.file_path}")
if self.on_delete:
self.on_delete(self.file_path)
return True
except PermissionError:
logger.error("Permission denied. File may be locked.")
return False
except OSError as e:
logger.error(f"Failed to delete file: {e}")
return False
def on_file_deleted(file_path: Path) -> None:
"""Callback executed after file deletion."""
logger.info(f"Cleanup complete for: {file_path}")
if __name__ == "__main__":
# Create test file
test_file = Path("sensitive_data.txt")
test_file.write_text("This will self-destruct!")
monitor = SelfDestructingFile(
target_file="sensitive_data.txt",
minutes=1,
on_delete=on_file_deleted,
check_interval=5
)
monitor.start_monitoring()
Output:
2026-02-14 10:44:48,471 - INFO - Monitoring: sensitive_data.txt
2026-02-14 10:44:48,471 - INFO - Scheduled deletion: 10:45:48
2026-02-14 10:45:48,473 - INFO - Successfully deleted: sensitive_data.txt
2026-02-14 10:45:48,473 - INFO - Cleanup complete for: sensitive_data.txt
Running as a Background Thread
To monitor files without blocking your main application:
import threading
import time
from pathlib import Path
def background_monitor(file_path: str, seconds: int) -> None:
"""Monitor and delete a file in a background thread."""
path = Path(file_path)
time.sleep(seconds)
if path.exists():
try:
path.unlink()
print(f"Background: Deleted {file_path}")
except OSError as e:
print(f"Background: Failed to delete - {e}")
def create_temp_file(filename: str, content: str, lifetime_seconds: int) -> Path:
"""
Create a temporary file that self-destructs after a duration.
Args:
filename: Name of the file to create
content: Content to write to the file
lifetime_seconds: How long the file should exist
Returns:
Path to the created file
"""
path = Path(filename)
path.write_text(content)
# Start background deletion thread
thread = threading.Thread(
target=background_monitor,
args=(filename, lifetime_seconds),
daemon=True
)
thread.start()
return path
if __name__ == "__main__":
# Create a file that deletes itself after 30 seconds
temp_file = create_temp_file(
filename="session_token.txt",
content="abc123xyz",
lifetime_seconds=30
)
print(f"Created: {temp_file}")
print("File will self-destruct in 30 seconds...")
# Main program continues
time.sleep(35)
print(f"File exists: {temp_file.exists()}")
Output:
Created: session_token.txt
File will self-destruct in 30 seconds...
Background: Deleted session_token.txt
File exists: False
Best Practices
Always include time.sleep() in monitoring loops. Without it, the script would consume 100% of a CPU core checking conditions millions of times per second.
On Windows especially, files may be locked by other programs. Always wrap deletion in try-except blocks to handle PermissionError gracefully.
Key Recommendations
| Practice | Reason |
|---|---|
Use configparser or .env | Avoid hardcoding durations; enable policy changes without code edits |
| Add sleep intervals | Prevent CPU waste in monitoring loops |
| Handle exceptions | Files may be locked or already deleted |
Use pathlib.Path | Modern, cross-platform file handling |
| Log operations | Track when files are created and deleted |
| Use daemon threads | Ensure threads don't prevent program exit |
Summary
- Use
pathlib.Path.unlink()for cross-platform file deletion. - Always sleep in monitoring loops to prevent CPU waste.
- Handle
PermissionErrorfor files that may be locked. - Use external configuration files for flexible timing policies.
- Consider background threads for non-blocking monitoring.