Time-travel debugging for FastAPI and Flask - record API cassettes, replay with mocked dependencies
Project description
Timetracer
Time-travel debugging for FastAPI and Flask - Record API requests, replay with mocked dependencies.
What is it?
Timetracer records real API request executions into portable cassettes and replays them locally by mocking dependency calls (HTTP, database, Redis).
Record once. Replay anywhere. Debug faster.
Use cases:
- Reproduce production/staging bugs quickly
- Build regression tests from real traffic
- Run offline demos
- Detect performance regressions
- Diff behavior between runs
Installation
# Core + all plugins
pip install timetracer[all]
# Or just what you need
pip install timetracer[fastapi,httpx] # FastAPI + HTTP
pip install timetracer[flask,httpx] # Flask + HTTP
pip install timetracer[sqlalchemy] # Database
pip install timetracer[redis] # Redis
pip install timetracer[s3] # S3 storage
Quickstart (3 Steps)
Step 1: Install
pip install timetracer[fastapi,httpx]
Step 2: Add 4 Lines to Your App
from fastapi import FastAPI
from timetracer.config import TraceConfig
from timetracer.integrations.fastapi import TimeTraceMiddleware
from timetracer.plugins import enable_httpx
app = FastAPI()
# Add these 2 lines to enable Timetracer
config = TraceConfig.from_env()
app.add_middleware(TimeTraceMiddleware, config=config)
# Optional: Enable httpx tracking
enable_httpx()
@app.post("/checkout")
async def checkout():
async with httpx.AsyncClient() as client:
response = await client.get("https://api.example.com/data")
return {"status": "ok"}
Step 3: Record and Replay
# Record requests
TIMETRACER_MODE=record uvicorn app:app
curl -X POST http://localhost:8000/checkout
# Check cassettes
ls ./cassettes/
# Output: 2026-01-16/POST__checkout__abc123.json
# Replay (mocked HTTP calls)
TIMETRACER_MODE=replay \
TIMETRACER_CASSETTE=./cassettes/2026-01-16/POST__checkout__abc123.json \
uvicorn app:app
Example Output:
# Recording
TIMETRACER [OK] recorded POST /checkout id=abc123 status=200 total=523ms deps=http.client:1
cassette: ./cassettes/2026-01-16/POST__checkout__abc123.json
# Replaying
TIMETRACER replay POST /checkout mocked=1 matched=OK runtime=45ms recorded=523ms
That's it! External HTTP calls are now mocked from the recorded cassette.
Flask Integration
from flask import Flask
from timetracer.integrations.flask import init_app
from timetracer.config import TraceConfig
app = Flask(__name__)
init_app(app, TraceConfig.from_env())
Features
Frameworks
- FastAPI - Full middleware support
- Flask - WSGI middleware support
Plugins
- httpx - Async/sync HTTP client
- requests - requests library
- SQLAlchemy - Database queries
- Redis - Redis commands
Storage
- Local filesystem - Default
- S3 - AWS S3 and S3-compatible (MinIO)
Analysis and Tools
- Diff engine - Compare cassettes
- HTML timeline - Visualize execution
- Hybrid replay - Mock some deps, keep others live
- Search and Index - Find cassettes by endpoint, status, date
Configuration
| Variable | Description | Default |
|---|---|---|
TIMETRACER_MODE |
off, record, replay |
off |
TIMETRACER_DIR |
Cassette directory | ./cassettes |
TIMETRACER_CASSETTE |
Replay cassette path | - |
TIMETRACER_SAMPLE_RATE |
Record fraction (0-1) | 1.0 |
TIMETRACER_ERRORS_ONLY |
Only record errors | false |
TIMETRACER_MOCK_PLUGINS |
Plugins to mock | all |
TIMETRACER_LIVE_PLUGINS |
Plugins to keep live | none |
CLI
# List cassettes
timetracer list --dir ./cassettes
# Show cassette details
timetracer show ./cassettes/.../POST__checkout.json --events
# Diff two cassettes
timetracer diff --a cassette1.json --b cassette2.json
# Generate timeline
timetracer timeline ./cassettes/POST__checkout.json --open
# Search cassettes
timetracer search --endpoint /checkout --method POST --errors
timetracer index --dir ./cassettes
# S3 operations
timetracer s3 upload ./cassettes/ -b my-bucket
timetracer s3 sync up -d ./cassettes -b my-bucket
Security
By default, Timetracer:
- Removes
Authorization,Cookie,Set-Cookieheaders - Masks sensitive body keys (
password,token, etc.) - Captures bodies only on errors by default
- Enforces size limits (64KB default)
Documentation
Roadmap
- v0.1-v0.3: Core, FastAPI, httpx, requests, diff, timeline
- v1.0: Hybrid replay, schema v1.0, CI/CD, docs
- v2.0: SQLAlchemy, Redis, Flask, S3 store
- v2.1: Cassette search/index
Contributing
Contributions welcome! See CONTRIBUTING.md.
License
MIT - see LICENSE.
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
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 timetracer-1.0.0.tar.gz.
File metadata
- Download URL: timetracer-1.0.0.tar.gz
- Upload date:
- Size: 64.0 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
00ccaf25d4e30bff99e01c5071ff0bcb087bdc88315623ffd4161141efa0197b
|
|
| MD5 |
ac4fdee90feb334dc463d3a06fbe787b
|
|
| BLAKE2b-256 |
f27a53c7bf3addf0749e8dcfd6dd8d2be652d422db430feae129e45fd7384e43
|
Provenance
The following attestation bundles were made for timetracer-1.0.0.tar.gz:
Publisher:
ci.yml on usv240/timetracer
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
timetracer-1.0.0.tar.gz -
Subject digest:
00ccaf25d4e30bff99e01c5071ff0bcb087bdc88315623ffd4161141efa0197b - Sigstore transparency entry: 830436706
- Sigstore integration time:
-
Permalink:
usv240/timetracer@0698fd7dcea3669873d57ef3d448b107729069d2 -
Branch / Tag:
refs/tags/v1.0.1 - Owner: https://github.com/usv240
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
ci.yml@0698fd7dcea3669873d57ef3d448b107729069d2 -
Trigger Event:
release
-
Statement type:
File details
Details for the file timetracer-1.0.0-py3-none-any.whl.
File metadata
- Download URL: timetracer-1.0.0-py3-none-any.whl
- Upload date:
- Size: 69.0 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
90001eee4dd0369d9296bb2157c6cd96a30fcfcab12e1ef5d865b536537e3c94
|
|
| MD5 |
9990ada1d695fc015150dae00522bde5
|
|
| BLAKE2b-256 |
2bf1ba31f57750182c0be9814a7b4a422d4faf1958d276e3142d94336349be99
|
Provenance
The following attestation bundles were made for timetracer-1.0.0-py3-none-any.whl:
Publisher:
ci.yml on usv240/timetracer
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
timetracer-1.0.0-py3-none-any.whl -
Subject digest:
90001eee4dd0369d9296bb2157c6cd96a30fcfcab12e1ef5d865b536537e3c94 - Sigstore transparency entry: 830436749
- Sigstore integration time:
-
Permalink:
usv240/timetracer@0698fd7dcea3669873d57ef3d448b107729069d2 -
Branch / Tag:
refs/tags/v1.0.1 - Owner: https://github.com/usv240
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
ci.yml@0698fd7dcea3669873d57ef3d448b107729069d2 -
Trigger Event:
release
-
Statement type: