truthound new reporter¶
Create a custom reporter with boilerplate code.
Synopsis¶
Arguments¶
| Argument | Required | Description |
|---|---|---|
name |
Yes | Reporter name (snake_case) |
Options¶
| Option | Short | Default | Description |
|---|---|---|---|
--output |
-o |
. |
Output directory |
--template |
-t |
basic |
Template type (basic, full) |
--author |
-a |
None | Author name |
--description |
-d |
None | Reporter description |
--tests/--no-tests |
--tests |
Generate test code | |
--docs/--no-docs |
--no-docs |
Generate documentation | |
--extension |
-e |
.txt |
Output file extension |
--content-type |
text/plain |
MIME Content-Type |
Description¶
The new reporter command generates reporter boilerplate:
- Creates reporter class file
- Generates test file (optional)
- Creates documentation (optional)
- Configures output format settings
Templates¶
| Template | Description | Best For |
|---|---|---|
basic |
Minimal reporter structure | Simple outputs |
full |
All features (filtering, sorting) | Production reporters |
Examples¶
Basic Reporter¶
Generated structure:
Generated code (my_reporter.py):
from truthound.reporters.base import Reporter
from truthound.validators.report import ValidationReport
class MyReporter(Reporter):
"""Custom reporter: my_reporter"""
name = "my_reporter"
extension = ".txt"
content_type = "text/plain"
def render(self, report: ValidationReport) -> str:
"""Render the validation report."""
lines = []
lines.append(f"Validation Report")
lines.append(f"=" * 40)
lines.append(f"Total Issues: {len(report.issues)}")
lines.append("")
for issue in report.issues:
lines.append(f"[{issue.severity}] {issue.validator}: {issue.message}")
return "\n".join(lines)
JSON Reporter¶
Generated code:
import json
from truthound.reporters.base import Reporter
from truthound.validators.report import ValidationReport
class JsonExportReporter(Reporter):
"""Custom reporter: json_export"""
name = "json_export"
extension = ".json"
content_type = "application/json"
def render(self, report: ValidationReport) -> str:
"""Render the validation report as JSON."""
data = {
"summary": {
"total_issues": len(report.issues),
"by_severity": self._count_by_severity(report),
},
"issues": [
{
"validator": issue.validator,
"column": issue.column,
"message": issue.message,
"severity": issue.severity,
}
for issue in report.issues
],
}
return json.dumps(data, indent=2)
def _count_by_severity(self, report):
counts = {}
for issue in report.issues:
counts[issue.severity] = counts.get(issue.severity, 0) + 1
return counts
HTML Reporter¶
Generated code:
from truthound.reporters.base import Reporter
from truthound.validators.report import ValidationReport
class HtmlExportReporter(Reporter):
"""Custom reporter: html_export"""
name = "html_export"
extension = ".html"
content_type = "text/html"
def render(self, report: ValidationReport) -> str:
"""Render the validation report as HTML."""
html = ['<!DOCTYPE html>', '<html>', '<head>',
'<title>Validation Report</title>',
'<style>',
'table { border-collapse: collapse; width: 100%; }',
'th, td { border: 1px solid #ddd; padding: 8px; text-align: left; }',
'.critical { background-color: #ffcccc; }',
'.high { background-color: #ffe6cc; }',
'.medium { background-color: #ffffcc; }',
'.low { background-color: #e6ffcc; }',
'</style>',
'</head>', '<body>',
f'<h1>Validation Report</h1>',
f'<p>Total Issues: {len(report.issues)}</p>',
'<table>',
'<tr><th>Severity</th><th>Validator</th><th>Column</th><th>Message</th></tr>']
for issue in report.issues:
html.append(
f'<tr class="{issue.severity.lower()}">'
f'<td>{issue.severity}</td>'
f'<td>{issue.validator}</td>'
f'<td>{issue.column or "-"}</td>'
f'<td>{issue.message}</td>'
f'</tr>'
)
html.extend(['</table>', '</body>', '</html>'])
return '\n'.join(html)
Full Featured Reporter¶
truthound new reporter detailed_report \
--template full \
--docs \
--author "Data Team" \
--description "Detailed validation report with filtering and sorting"
Generated structure:
Generated code (detailed_report.py with full template):
from typing import Optional, List
from truthound.reporters.base import Reporter
from truthound.validators.report import ValidationReport, ValidationIssue
class DetailedReportReporter(Reporter):
"""Detailed validation report with filtering and sorting"""
name = "detailed_report"
extension = ".txt"
content_type = "text/plain"
def __init__(
self,
min_severity: Optional[str] = None,
sort_by: str = "severity",
include_validators: Optional[List[str]] = None,
exclude_validators: Optional[List[str]] = None,
):
self.min_severity = min_severity
self.sort_by = sort_by
self.include_validators = include_validators
self.exclude_validators = exclude_validators
def render(self, report: ValidationReport) -> str:
"""Render the validation report with filtering and sorting."""
issues = self._filter_issues(report.issues)
issues = self._sort_issues(issues)
return self._format_output(issues)
def _filter_issues(self, issues: List[ValidationIssue]) -> List[ValidationIssue]:
# Filtering logic
...
def _sort_issues(self, issues: List[ValidationIssue]) -> List[ValidationIssue]:
# Sorting logic
...
def _format_output(self, issues: List[ValidationIssue]) -> str:
# Formatting logic
...
XML Reporter¶
truthound new reporter xml_export \
--extension .xml \
--content-type application/xml \
--description "XML format validation report"
Custom Output Directory¶
Creates files in ./reporters/ directory.
Template Comparison¶
| Feature | basic | full |
|---|---|---|
| Basic rendering | Yes | Yes |
| Filtering | - | Yes |
| Sorting | - | Yes |
| Configuration | - | Yes |
| Tests | Yes | Yes |
| Documentation | Optional | Optional |
Common Content Types¶
| Format | Extension | Content-Type |
|---|---|---|
| Plain Text | .txt |
text/plain |
| JSON | .json |
application/json |
| HTML | .html |
text/html |
| XML | .xml |
application/xml |
| CSV | .csv |
text/csv |
| Markdown | .md |
text/markdown |
Use Cases¶
1. Custom JSON Output¶
truthound new reporter api_response \
--extension .json \
--content-type application/json \
--description "API-friendly JSON response format"
2. Slack-Friendly Format¶
truthound new reporter slack_message \
--template full \
--extension .txt \
--description "Slack message format with emoji indicators"
3. CSV Export¶
truthound new reporter csv_export \
--extension .csv \
--content-type text/csv \
--description "CSV export for spreadsheet analysis"
4. Custom HTML Dashboard¶
truthound new reporter dashboard \
--template full \
--extension .html \
--content-type text/html \
--docs
Generated Test Code¶
import pytest
from my_reporter import MyReporter
from truthound.validators.report import ValidationReport, ValidationIssue
class TestMyReporter:
def test_render_empty_report(self):
reporter = MyReporter()
report = ValidationReport(issues=[])
result = reporter.render(report)
assert "Total Issues: 0" in result
def test_render_with_issues(self):
reporter = MyReporter()
report = ValidationReport(issues=[
ValidationIssue(
validator="test",
column="col1",
message="Test issue",
severity="MEDIUM",
)
])
result = reporter.render(report)
assert "Test issue" in result
assert "MEDIUM" in result
Exit Codes¶
| Code | Condition |
|---|---|
| 0 | Success |
| 1 | Generation error |
| 2 | Invalid arguments |
Related Commands¶
new validator- Create custom validatornew plugin- Create plugin packagenew templates- List available templates