A lightweight, offline-first crash debugging and developer handoff system.
Project description
FaultSnap
1. What is FaultSnap?
FaultSnap is a black-box recorder for Python applications.
When your program crashes, FaultSnap captures the execution context, stores it in a portable .faultsnap archive, and allows another developer to inspect the crash without reproducing it.
2. Why FaultSnap Exists
When an exception occurs, Python provides a standard traceback. However, tracebacks only give you the file and line number. They don't tell you the state of variables at the time of the crash.
user = None
print(user.name) # AttributeError: 'NoneType' object has no attribute 'name'
Why is user None? What were the variables leading up to this? With FaultSnap, you can inspect every local variable, frame by frame, exactly as it was when the crash occurred.
3. Installation
pip install faultsnap
To enable offline HTML report generation:
pip install faultsnap[html]
4. Quick Start
import faultsnap
faultsnap.install()
1 / 0
Output:
[FaultSnap] Crash captured. Saved to FaultSnaps/ZeroDivisionError/2026-06-13/1eaee423/crash_232934_1eaee423.faultsnap
5. How FaultSnap Works
- Capture: Intercepts unhandled exceptions globally or via framework middleware.
- Serialize: Traverses the execution stack safely, truncating large structures and handling circular references to prevent cascading failures.
- Mask: Redacts sensitive data (like passwords, keys, and tokens) matching predefined or custom regex patterns.
- Fingerprint: Computes a unique SHA-256 hash based on the execution path to group identical crashes.
- Package: Generates a
.faultsnapZIP archive with manifest metadata and a standalone HTML report. - Analyze: Use the CLI to search, inspect, and visualize crashes from the repository.
6. Crash Repository Structure
FaultSnap organizes all crashes in a central FaultSnaps/ directory to prevent cluttering your project root. The repository maintains an index.json to allow fast searching and a latest/ folder pointing to the most recent crash.
FaultSnaps/
├── index.json
├── latest/
│ ├── latest.faultsnap
│ └── latest.html
└── ZeroDivisionError/
└── 2026-06-13/
└── 1eaee423/
├── crash_232934.faultsnap
├── crash_232934.html
└── metadata.json
7. Complete CLI Reference
Manage and analyze your crashes directly from the terminal.
faultsnap list
Purpose: Shows all stored crashes in a tabular view.
Syntax: faultsnap list
Example Output:
Timestamp Exception Fingerprint
----------------------------------------------------------------
2026-06-13 23:29:34 ZeroDivisionError 1eaee423
2026-06-13 23:31:15 AttributeError 3abf9121
faultsnap latest
Purpose: Inspect the most recent crash.
Syntax: faultsnap latest
Example: Immediately displays the metadata and exception string for the crash in FaultSnaps/latest/.
faultsnap search
Purpose: Search the crash index by exception type or fingerprint.
Syntax: faultsnap search <term>
Example: faultsnap search ZeroDivisionError or faultsnap search 1eaee423
faultsnap stats
Purpose: Display repository statistics.
Syntax: faultsnap stats
Example Output:
Total Crashes: 154
Unique Fingerprints: 23
Most Common Error: AttributeError
Oldest Crash: 2026-05-01
Newest Crash: 2026-06-13
faultsnap clean
Purpose: Remove expired reports based on the retention policy configured via faultsnap.configure(max_days_to_keep=30).
Syntax: faultsnap clean
faultsnap inspect
Purpose: View high-level metadata and the raw traceback for a specific capsule.
Syntax: faultsnap inspect <file>
Example: faultsnap inspect FaultSnaps/latest/latest.faultsnap
faultsnap stack
Purpose: Render an interactive tree view of the call stack.
Syntax: faultsnap stack <file>
faultsnap vars
Purpose: View local variables for every execution frame.
Syntax: faultsnap vars <file>
faultsnap env
Purpose: View captured environment variables safely.
Syntax: faultsnap env <file>
faultsnap fingerprint
Purpose: Print the unique hash of the crash.
Syntax: faultsnap fingerprint <file>
faultsnap diff
Purpose: Compare metadata between two different crash files.
Syntax: faultsnap diff <file1> <file2>
faultsnap html
Purpose: Generate a standalone HTML dashboard for a specific capsule.
Syntax: faultsnap html <file>
8. HTML Reports
The HTML report provides an interactive diagnostic dashboard that operates completely offline. It features:
- Search & Variable Filtering: Quickly find specific variables across deep call stacks.
- Stack Exploration: Expand/collapse frames to view line-by-line context and local state.
- Execution Graph: A visual flow of the exception path via a bundled Mermaid.js graph.
9. Framework Integrations
FaultSnap provides explicit integration handlers for major frameworks.
AsyncIO
import asyncio
from faultsnap.integrations.asyncio import install
async def main():
install()
# Async execution
Multiprocessing
from faultsnap.integrations.multiprocessing import install
install()
Flask
from flask import Flask
from faultsnap.integrations.flask import install
app = Flask(__name__)
install(app)
FastAPI
from fastapi import FastAPI
from faultsnap.integrations.fastapi import install
app = FastAPI()
install(app)
Django
Add to MIDDLEWARE in settings.py:
MIDDLEWARE = [
'faultsnap.integrations.django.FaultSnapMiddleware',
]
Streamlit
from faultsnap.integrations.streamlit import install
install()
Pytest
In conftest.py:
pytest_plugins = ["faultsnap.integrations.pytest_plugin"]
10. Security Features
- Secret Masking: Automatically redacts values for keys containing terms like
password,secret,token,key, andauth. - Safe Environment Capture: Captures only benign OS variables (
PATH,OS,TERM) by default to prevent accidental credential leaks. - Offline Operation: FaultSnap operates strictly offline. It never transmits data externally and HTML reports embed all necessary dependencies.
- HTML Escaping: Strict Jinja2 autoescaping prevents XSS vulnerabilities in generated reports.
11. Performance
- Depth Limits: Traversal stops at a safe recursion depth (
max_depth=5). - Truncation: Lists and strings are truncated to prevent infinite evaluation and memory exhaustion (
max_items=50). - Memory Protection: A global persistent counter enforces a hard limit on the total number of objects processed (
max_total_items=10000).
12. Architecture Overview
core.py: Injects hooks into Python runtimes and extracts context fromf_locals.serializer.py: Safely evaluates and truncates arbitrary Python objects into JSON-friendly formats.mask.py: Scans keys and redacts sensitive data using regex.fingerprint.py: Generates a unified SHA-256 hash representing the crash path.capsule.py: Compresses the payload into a.faultsnapZIP archive.storage.py: Organizes artifacts into the hierarchicalFaultSnaps/repository, updates indexes, and handles retention.html.py: Combines crash metadata with Jinja2 templates for interactive offline reports.cli.py: Powers the interactive terminal inspector.
13. FAQ
Q: Why is my variable truncated?
A: FaultSnap imposes strict bounds (max_items, max_string_len) to ensure the crash capturer never causes an Out-Of-Memory error itself. You can increase these via faultsnap.configure().
Q: Why are passwords masked? A: To prevent accidental exfiltration or logging of secrets in developer crash dumps.
Q: How do I open a .faultsnap file?
A: Use the FaultSnap CLI (faultsnap inspect <file>) or generate an HTML report (faultsnap html <file>).
Q: Can I share crash files with teammates?
A: Yes. The .faultsnap and .html files are fully standalone. You can share them directly with other developers to analyze the crash offline.
Q: Does FaultSnap send data anywhere? A: No. It operates entirely offline.
14. Contributing
Contributions are welcome! Please ensure you run the pytest suite before submitting pull requests.
15. License
MIT License.
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 faultsnap-1.0.1.tar.gz.
File metadata
- Download URL: faultsnap-1.0.1.tar.gz
- Upload date:
- Size: 928.0 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
ca272ccb8a76eb1d1839302205f7b9cfabc4931d2a0c5edf516533748bd9829e
|
|
| MD5 |
3a508d486a77f0ce83d996b9753181cc
|
|
| BLAKE2b-256 |
cbc6365d3b6b05a4a7d1b5e5a3f87c9b1556b55af7c2aae636b1503e54ad7566
|
Provenance
The following attestation bundles were made for faultsnap-1.0.1.tar.gz:
Publisher:
publish.yml on Vineshnayak/PyPi
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
faultsnap-1.0.1.tar.gz -
Subject digest:
ca272ccb8a76eb1d1839302205f7b9cfabc4931d2a0c5edf516533748bd9829e - Sigstore transparency entry: 1817808707
- Sigstore integration time:
-
Permalink:
Vineshnayak/PyPi@0dffcf28ccb2e041fa050b6831a998f2b1dd137d -
Branch / Tag:
refs/tags/v1.0.1 - Owner: https://github.com/Vineshnayak
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@0dffcf28ccb2e041fa050b6831a998f2b1dd137d -
Trigger Event:
push
-
Statement type:
File details
Details for the file faultsnap-1.0.1-py3-none-any.whl.
File metadata
- Download URL: faultsnap-1.0.1-py3-none-any.whl
- Upload date:
- Size: 934.5 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
1caedbf8fa35034de7bcb41ae01c5586735e344cc6155cf3b57e2840495f8048
|
|
| MD5 |
5da4f9027d0564dbc065fa5b13ac1676
|
|
| BLAKE2b-256 |
9e283d3dc86d986ed1164cfd934c72d056f73c2cb3051321aecf59240362c151
|
Provenance
The following attestation bundles were made for faultsnap-1.0.1-py3-none-any.whl:
Publisher:
publish.yml on Vineshnayak/PyPi
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
faultsnap-1.0.1-py3-none-any.whl -
Subject digest:
1caedbf8fa35034de7bcb41ae01c5586735e344cc6155cf3b57e2840495f8048 - Sigstore transparency entry: 1817808951
- Sigstore integration time:
-
Permalink:
Vineshnayak/PyPi@0dffcf28ccb2e041fa050b6831a998f2b1dd137d -
Branch / Tag:
refs/tags/v1.0.1 - Owner: https://github.com/Vineshnayak
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@0dffcf28ccb2e041fa050b6831a998f2b1dd137d -
Trigger Event:
push
-
Statement type: