Source code for assets_guardian.core.domain.models.report

from collections.abc import Iterable, Iterator

from assets_guardian.core.domain.models.finding import Finding, SeverityType


[docs] class Report: """Container for audit findings, allowing tracking of metrics. Can operate either in "memory" mode (classic list) or in "streaming" mode (external iterable such as a cache) to prevent RAM saturation. """ def __init__(self, findings: Iterable[Finding] | None = None) -> None: """Initializes the report, possibly in streaming mode. Args: findings: An optional iterable of findings (e.g., from cache). If present, the report switches to streaming mode. """ self._findings_list: list[Finding] = [] self._external_iterable: Iterable[Finding] | None = findings self._counts_by_severity: dict[SeverityType, int] = dict.fromkeys(SeverityType, 0) if findings: self.extend(findings)
[docs] def add_finding(self, finding: Finding) -> None: """Adds a finding to the report and updates severity counters. Args: finding: The detected anomaly to integrate. """ # We only store in the internal list if we do not have an external iterable # or if we want to force keeping in memory. if self._external_iterable is None: self._findings_list.append(finding) self._counts_by_severity[finding.severity] += 1
[docs] def extend(self, findings: Iterable[Finding]) -> None: """Adds multiple findings to the report in bulk. Args: findings: An iterable of findings to process. """ for finding in findings: self.add_finding(finding)
@property def total_count(self) -> int: """Total count of detected findings.""" return sum(self._counts_by_severity.values())
[docs] def get_count_by_severity(self, severity: SeverityType) -> int: """Returns the count of findings for a given severity.""" return self._counts_by_severity.get(severity, 0)
def __iter__(self) -> Iterator[Finding]: """Allows iterating over findings. Prioritizes the external iterable (streaming) if present, otherwise the internal list. """ if self._external_iterable is not None: return iter(self._external_iterable) return iter(self._findings_list) def __len__(self) -> int: """Enables the use of len(report).""" return self.total_count