Scan dependencies for known vulnerabilities and licenses.
Overall
score
61%
Safety CLI provides a comprehensive formatting and output system that supports multiple report formats for vulnerability scanning, license checking, and other analysis results. The system uses a strategy pattern with pluggable formatters for different output types.
Import Statements:
from safety.formatter import FormatterAPI, SafetyFormatter
from safety.formatters.json import JsonReport, build_json_report
from safety.formatters.text import TextReport
from safety.formatters.screen import ScreenReport
from safety.formatters.html import HTMLReport
from safety.formatters.bare import BareReport
from safety.models import SafetyEncoderDescription: Abstract base class defining the interface for all output formatters.
class FormatterAPI:
"""Strategy pattern base class for report formatters."""
def __init__(self, **kwargs: Any) -> None:
"""
Initialize formatter with configuration options.
Args:
**kwargs: Formatter-specific configuration options
"""
@abstractmethod
def render_vulnerabilities(
self,
announcements: List[Dict[str, Any]], # Platform announcements
vulnerabilities: List[Dict[str, Any]], # Found vulnerabilities
remediations: Dict[str, Any], # Remediation suggestions
full: bool, # Include full details
packages: List[Dict[str, Any]], # Scanned packages
fixes: Tuple = () # Applied fixes
) -> Optional[str]:
"""
Render vulnerability scan results.
Args:
announcements: Platform announcements and notices
vulnerabilities: Detected vulnerabilities
remediations: Available remediation options
full: Whether to include detailed information
packages: List of analyzed packages
fixes: Applied automatic fixes
Returns:
Optional[str]: Formatted report output
"""
@abstractmethod
def render_licenses(
self,
announcements: List[Dict[str, Any]], # Platform announcements
licenses: List[Dict[str, Any]] # License information
) -> Optional[str]:
"""
Render license compliance report.
Args:
announcements: Platform announcements
licenses: Package license information
Returns:
Optional[str]: Formatted license report
"""
@abstractmethod
def render_announcements(
self,
announcements: List[Dict[str, Any]] # Platform announcements
) -> Optional[str]:
"""
Render platform announcements.
Args:
announcements: Platform announcements and notices
Returns:
Optional[str]: Formatted announcements
"""Description: Factory class that creates appropriate formatter instances based on output format specification.
class SafetyFormatter(FormatterAPI):
"""Factory formatter that delegates to specific format implementations."""
def __init__(self, output: str, **kwargs: Any) -> None:
"""
Initialize formatter factory with target output format.
Args:
output (str): Target output format ('json', 'html', 'bare', 'text', 'screen')
**kwargs: Additional configuration passed to specific formatter
"""
# Supported output formats
SUPPORTED_FORMATS = [
'json', # Machine-readable JSON
'html', # Web-viewable HTML report
'bare', # Minimal text output
'text', # Formatted text report
'screen' # Rich terminal output (default)
]Example Usage:
from safety.formatter import SafetyFormatter
# Create JSON formatter
json_formatter = SafetyFormatter(output='json')
# Create HTML formatter with custom template
html_formatter = SafetyFormatter(
output='html',
template_dir='/custom/templates'
)
# Create screen formatter for terminal output
screen_formatter = SafetyFormatter(output='screen')Description: Generates machine-readable JSON reports for vulnerability and license data.
class JsonReport(FormatterAPI):
"""JSON formatter for machine-readable output."""
def __init__(self, version: str = "3.0", **kwargs: Any) -> None:
"""
Initialize JSON formatter.
Args:
version (str): JSON schema version to use
**kwargs: Additional configuration options
"""
def render_vulnerabilities(
self,
announcements: List[Dict[str, Any]],
vulnerabilities: List[Dict[str, Any]],
remediations: Dict[str, Any],
full: bool,
packages: List[Dict[str, Any]],
fixes: Tuple = ()
) -> str:
"""
Generate JSON vulnerability report.
Returns:
str: JSON-formatted vulnerability report
"""
def render_licenses(
self,
announcements: List[Dict[str, Any]],
licenses: List[Dict[str, Any]]
) -> str:
"""
Generate JSON license report.
Returns:
str: JSON-formatted license report
"""def build_json_report(
announcements: List[Dict], # Platform announcements
vulnerabilities: List[Dict], # Vulnerability data
remediations: Dict[str, Any], # Remediation options
packages: List[Any] # Package information
) -> Dict[str, Any]:
"""
Build structured JSON report from scan results.
Args:
announcements: Platform announcements and notices
vulnerabilities: Detected vulnerabilities
remediations: Available remediation suggestions
packages: Scanned package information
Returns:
Dict[str, Any]: Structured report data ready for JSON serialization
"""JSON Report Structure:
{
"report_meta": {
"scan_target": "project_directory",
"timestamp": "2024-01-15T10:30:00Z",
"safety_version": "3.6.1",
"vulnerabilities_found": 2,
"vulnerabilities_ignored": 1,
"remediations_recommended": 1
},
"vulnerabilities": [
{
"vulnerability_id": "VULN-12345",
"package_name": "requests",
"installed_version": "2.20.0",
"affected_versions": ">=2.0.0,<2.20.1",
"advisory": "Security vulnerability description",
"cve": {
"name": "CVE-2023-12345",
"cvssv3": 7.5
},
"severity": {
"source": "safety",
"cvssv3": 7.5
},
"fixed_versions": ["2.20.1", "2.21.0"],
"ignored": false,
"more_info_url": "https://safety.com/vuln/12345"
}
],
"ignored_vulnerabilities": [...],
"remediations": {...},
"packages": [...],
"announcements": [...]
}Description: Rich terminal formatter with colors, formatting, and interactive elements.
class ScreenReport(FormatterAPI):
"""Rich terminal formatter for interactive console output."""
def __init__(self,
console=None, # Rich console instance
emoji: bool = True, # Enable emoji output
**kwargs: Any) -> None:
"""
Initialize screen formatter.
Args:
console: Rich console instance for output
emoji: Enable emoji in output
**kwargs: Additional configuration
"""
def render_vulnerabilities(self, ...) -> str:
"""
Generate rich terminal vulnerability report with:
- Color-coded severity levels
- Formatted tables and lists
- Progress indicators
- Interactive elements
"""
def render_licenses(self, ...) -> str:
"""Generate formatted license compliance report."""Screen Output Features:
Description: Plain text formatter for non-interactive environments and file output.
class TextReport(FormatterAPI):
"""Plain text formatter for file output and non-interactive terminals."""
def render_vulnerabilities(self, ...) -> str:
"""
Generate plain text vulnerability report suitable for:
- File output
- Email reports
- CI/CD logs
- Non-interactive terminals
"""
def render_licenses(self, ...) -> str:
"""Generate plain text license report."""Description: HTML formatter for web-viewable reports with styling and interactivity.
class HTMLReport(FormatterAPI):
"""HTML formatter for web-viewable vulnerability reports."""
def __init__(self,
template_dir: Optional[str] = None, # Custom template directory
**kwargs: Any) -> None:
"""
Initialize HTML formatter.
Args:
template_dir: Custom Jinja2 template directory
**kwargs: Additional template variables
"""
def render_vulnerabilities(self, ...) -> str:
"""
Generate HTML vulnerability report with:
- Styled tables and layouts
- Interactive filtering
- Sortable columns
- Embedded CSS and JavaScript
"""HTML Report Features:
Description: Minimal formatter for machine processing and scripting integration.
class BareReport(FormatterAPI):
"""Minimal formatter for machine processing and automation."""
def render_vulnerabilities(self, ...) -> str:
"""
Generate minimal vulnerability output:
- One vulnerability per line
- Tab or delimiter-separated fields
- No headers or formatting
- Suitable for grep, awk, etc.
"""
def render_licenses(self, ...) -> str:
"""Generate minimal license output."""Bare Output Format:
package_name\tvulnerability_id\tseverity\tinstalled_version\tfixed_version
requests\tVULN-12345\thigh\t2.20.0\t2.20.1
django\tVULN-67890\tcritical\t3.0.0\t3.0.14Description: Custom JSON encoder for Safety-specific data types and models.
from safety.models import SafetyEncoder
class SafetyEncoder(json.JSONEncoder):
"""Custom JSON encoder for Safety data structures."""
def default(self, obj: Any) -> Any:
"""
Serialize Safety-specific objects to JSON-compatible formats.
Handles:
- Vulnerability objects
- Package objects
- DateTime objects
- Custom data classes
Args:
obj: Object to serialize
Returns:
Any: JSON-serializable representation
"""Example Usage:
import json
from safety.models import SafetyEncoder
# Serialize vulnerability data with custom encoder
vulnerability_data = {...} # Vulnerability objects
json_output = json.dumps(
vulnerability_data,
cls=SafetyEncoder,
indent=2
)from safety.output_utils import get_report_brief_info, should_add_nl
def get_report_brief_info(
as_dict: bool = False, # Return as dictionary
report_type: int = 1, # Report type identifier
vulnerabilities_found: int = 0, # Number of vulnerabilities
vulnerabilities_ignored: int = 0, # Number ignored
remediations_recommended: Dict = None # Remediation suggestions
) -> Union[str, Dict[str, Any]]:
"""
Generate brief report summary information.
Args:
as_dict: Return structured data instead of formatted string
report_type: Type of report (1=vulnerability, 2=license, etc.)
vulnerabilities_found: Count of active vulnerabilities
vulnerabilities_ignored: Count of ignored vulnerabilities
remediations_recommended: Available remediation options
Returns:
Union[str, Dict]: Brief report summary
"""
def should_add_nl(console_output: str) -> bool:
"""
Determine if newline should be added to console output.
Args:
console_output (str): Console output string
Returns:
bool: True if newline should be added
"""Safety supports versioned report schemas for backward compatibility:
from safety.formatters.schemas.v3_0 import ScanReportV30
class ScanReportV30(BaseModel):
"""Pydantic model for v3.0 scan report schema."""
report_meta: ReportMeta # Report metadata
vulnerabilities: List[VulnerabilityModel] # Vulnerability findings
ignored_vulnerabilities: List[VulnerabilityModel] # Ignored vulnerabilities
remediations: Dict[str, Any] # Remediation suggestions
packages: List[PackageModel] # Scanned packages
announcements: List[AnnouncementModel] # Platform announcementsFormatters can be configured through various options:
# JSON formatter with specific version
json_formatter = SafetyFormatter(
output='json',
version='3.0',
indent=4,
sort_keys=True
)
# HTML formatter with custom templates
html_formatter = SafetyFormatter(
output='html',
template_dir='/path/to/custom/templates',
theme='dark',
include_css=True
)
# Screen formatter with custom console
from rich.console import Console
custom_console = Console(width=120, theme='github-dark')
screen_formatter = SafetyFormatter(
output='screen',
console=custom_console,
emoji=False
)HTML formatter supports custom Jinja2 templates:
<!-- Custom vulnerability report template -->
<!DOCTYPE html>
<html>
<head>
<title>{{ report_title }} - Security Report</title>
<style>{{ embedded_css }}</style>
</head>
<body>
<h1>{{ report_title }}</h1>
{% if vulnerabilities %}
<table class="vulnerabilities">
<thead>
<tr>
<th>Package</th>
<th>Vulnerability</th>
<th>Severity</th>
<th>Fixed Version</th>
</tr>
</thead>
<tbody>
{% for vuln in vulnerabilities %}
<tr class="severity-{{ vuln.severity.lower() }}">
<td>{{ vuln.package_name }}</td>
<td>{{ vuln.vulnerability_id }}</td>
<td>{{ vuln.severity }}</td>
<td>{{ vuln.fixed_versions|join(', ') }}</td>
</tr>
{% endfor %}
</tbody>
</table>
{% endif %}
</body>
</html>from safety.formatter import SafetyFormatter
# Sample data
vulnerabilities = [...] # Vulnerability objects
packages = [...] # Package objects
announcements = [...] # Announcement objects
remediations = {...} # Remediation suggestions
# Generate JSON report
json_formatter = SafetyFormatter(output='json')
json_report = json_formatter.render_vulnerabilities(
announcements=announcements,
vulnerabilities=vulnerabilities,
remediations=remediations,
full=True,
packages=packages
)
# Save to file
with open('security-report.json', 'w') as f:
f.write(json_report)from safety.formatter import SafetyFormatter
# Generate reports in multiple formats
formats = ['json', 'html', 'text']
reports = {}
for format_type in formats:
formatter = SafetyFormatter(output=format_type)
reports[format_type] = formatter.render_vulnerabilities(
announcements=announcements,
vulnerabilities=vulnerabilities,
remediations=remediations,
full=True,
packages=packages
)
# Save each format
for format_type, content in reports.items():
filename = f'security-report.{format_type}'
with open(filename, 'w') as f:
f.write(content)# Generate license compliance report
license_data = [...] # License information
formatter = SafetyFormatter(output='html')
license_report = formatter.render_licenses(
announcements=announcements,
licenses=license_data
)
# Display in terminal
formatter = SafetyFormatter(output='screen')
terminal_output = formatter.render_licenses(
announcements=announcements,
licenses=license_data
)
print(terminal_output)from safety.formatters.json import build_json_report
import json
# Build structured report data
report_data = build_json_report(
announcements=announcements,
vulnerabilities=vulnerabilities,
remediations=remediations,
packages=packages
)
# Custom processing
report_data['custom_metadata'] = {
'scan_time': datetime.now().isoformat(),
'project_name': 'my-project',
'environment': 'production'
}
# Serialize with custom options
json_output = json.dumps(
report_data,
cls=SafetyEncoder,
indent=2,
sort_keys=True,
ensure_ascii=False
)This comprehensive formatter documentation covers all aspects of Safety CLI's output and formatting system, enabling developers to generate reports in their preferred format and integrate security scanning results into their workflows and tooling.
Install with Tessl CLI
npx tessl i tessl/pypi-safetydocs
evals
scenario-1
scenario-2
scenario-3
scenario-4
scenario-5
scenario-6
scenario-7
scenario-8
scenario-9
scenario-10