Lightweight HTTP request/response logger and debugger for FastAPI
Project description
reqtrace
Lightweight HTTP request/response logger for FastAPI. Designed for developers who need clear, structured debug output without writing print() everywhere.
Features
- Auto-log every request & response via FastAPI middleware
- Colorized terminal output with status color coding
- File output in JSON (NDJSON) or plain text format
- Configurable output mode: terminal, file, or both
- Auto-diff mode — detects response changes per endpoint automatically
- Manual diff — compare any two responses on demand
- Press
cto clear terminal while server is running - Authorization header auto-masking
Installation
pip install reqtrace
Quickstart
from fastapi import FastAPI
from reqtrace import ReqTrace
from reqtrace.middleware import ReqTraceMiddleware
rt = ReqTrace(output="terminal")
app = FastAPI()
app.add_middleware(ReqTraceMiddleware, config=rt.config)
That's it — every request will be logged automatically.
Output Modes
# Terminal only (default)
rt = ReqTrace(output="terminal")
# File only — JSON format
rt = ReqTrace(output="file", file_path="logs/trace.json")
# File only — plain text
rt = ReqTrace(output="file", file_path="logs/trace.txt", file_format="txt")
# Both terminal and file
rt = ReqTrace(output="both", file_path="logs/trace.json")
# Disabled (useful for production)
rt = ReqTrace(output="terminal", enabled=False)
Auto-Diff
Enable auto-diff to automatically compare each response against the previous one for the same endpoint. Useful for detecting unintended changes after modifying your code.
rt = ReqTrace(output="terminal", diff=True)
# With file output
rt = ReqTrace(output="both", file_path="logs/trace.json", diff=True)
On the first request to an endpoint, reqtrace saves a snapshot. On every subsequent request to the same endpoint, it compares and displays what changed:
┌─ DIFF GET /users ────────────────────────────────────────────
+1 -0 ~0
+ data[2] {'id': 3, 'name': 'Diz', 'email': 'diz@example.com'}
└──────────────────────────────────────────────────────────────
Diff symbols:
+— field or item added-— field or item removed~— value or type changed
When there are no changes:
┌─ DIFF GET /users ────────────────────────────────────────────
No changes detected
└──────────────────────────────────────────────────────────────
Terminal Output Example
┌─ REQUEST ────────────────────────────────────────────────────
POST /api/users
content-type: application/json
Body:
{
"name": "Diz",
"email": "diz@mail.com"
}
├─ RESPONSE ───────────────────────────────────────────────────
Status : 422 43.2ms
Body:
{
"detail": [{"loc": ["body", "email"], "msg": "value is not a valid email"}]
}
└──────────────────────────────────────────────────────────────
Status codes are color-coded:
- 🟢
2xx— green - 🟡
3xx— yellow - 🔴
4xx— red - 🟣
5xx— magenta
Clear Terminal
While the server is running, press c to clear the terminal output. The key can be customized or disabled:
# Custom key
rt = ReqTrace(output="terminal", clear_key="r")
# Disable
rt = ReqTrace(output="terminal", clear_key=None)
JSON Log Format
Each entry is one JSON object per line (NDJSON), easy to stream and parse:
{"timestamp": "2026-03-23T10:15:00+00:00", "method": "POST", "url": "/api/users", "status_code": 422, "latency_ms": 43.2, "request_headers": {...}, "request_body": {"name": "Diz"}, "response_body": {...}}
Diff entries are written as a separate record with "type": "diff":
{"timestamp": "2026-03-23T10:16:00+00:00", "type": "diff", "method": "GET", "url": "/users", "changes": {"added": [{"path": "data[2]", "value": {...}}], "removed": [], "changed": []}, "has_changes": true}
Configuration Reference
| Parameter | Type | Default | Description |
|---|---|---|---|
output |
"terminal" | "file" | "both" |
"terminal" |
Where to send log output |
file_path |
str |
None |
Log file path. Required if output is "file" or "both" |
file_format |
"json" | "txt" |
"json" |
Log file format |
enabled |
bool |
True |
Master on/off switch |
diff |
bool |
False |
Enable auto-diff per endpoint |
clear_key |
str | None |
"c" |
Terminal clear shortcut. None to disable |
Requirements
- Python >= 3.10
- FastAPI / Starlette >= 0.27.0
Changelog
v0.2.0
- Auto-diff mode (
diff=True) — compares responses per endpoint automatically - Diff output in both terminal and file
- Press
cto clear terminal (configurable viaclear_key)
v0.1.0
- Initial release
- Request/response logging via FastAPI middleware
- Terminal (colorized) and file (JSON/txt) output
Roadmap
v0.3.0— Filter log by route, method, or status codev0.3.0— Flask/Django supportv0.4.0— Web UI log viewer
License
MIT
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 reqtrace_py-0.2.0.tar.gz.
File metadata
- Download URL: reqtrace_py-0.2.0.tar.gz
- Upload date:
- Size: 11.5 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
65ddf7fd5d4744740cbb9745673314662570996321a192da2c30b026654ac5c7
|
|
| MD5 |
3ebdd9670191eb0199e6e16dbf30ce8b
|
|
| BLAKE2b-256 |
a90267aa7adb3fa5aa100921ecae6a88af1daa34c4df8134f7a404973d15ec18
|
File details
Details for the file reqtrace_py-0.2.0-py3-none-any.whl.
File metadata
- Download URL: reqtrace_py-0.2.0-py3-none-any.whl
- Upload date:
- Size: 12.1 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
5e15ac16b88335c8446a568f6ccda48b5e2f49a5f155a323f3ff2e0430a0cbe0
|
|
| MD5 |
7e73ead1b7ac13302ee5cc7fe65a110e
|
|
| BLAKE2b-256 |
298cf5ff43c42735e8ab1425b5b29e7633c13a2878a6315ccac37da40e56c05b
|