From e3cb3412d69154869644666ab3a1971e1cf812be Mon Sep 17 00:00:00 2001 From: Josh Hawkins <32435876+hawkeye217@users.noreply.github.com> Date: Fri, 30 Oct 2026 21:44:11 -0500 Subject: [PATCH] docstrings --- frigate/analytics/collectors/cameras.py | 5 ++++- frigate/analytics/collectors/detection.py | 1 + frigate/analytics/collectors/features.py | 1 + frigate/analytics/collectors/hardware.py | 1 + frigate/analytics/collectors/health.py | 1 + frigate/analytics/collectors/install.py | 1 + frigate/analytics/report.py | 1 + frigate/analytics/reporter.py | 1 + frigate/analytics/state.py | 1 + frigate/test/test_analytics_collectors_cameras.py | 3 ++- generate_analytics_schema.py | 1 + 11 files changed, 15 insertions(+), 2 deletions(-) diff --git a/frigate/analytics/collectors/cameras.py b/frigate/analytics/collectors/cameras.py index 10dff999bb..ebc51d7d70 100644 --- a/frigate/analytics/collectors/cameras.py +++ b/frigate/analytics/collectors/cameras.py @@ -101,6 +101,7 @@ def object_masks(camera: CameraConfig) -> int: def collect(ctx: ReportContext) -> CamerasSection: + """Count camera settings across the cameras enabled in config.""" cameras = { name: camera for name, camera in ctx.config.cameras.items() @@ -171,7 +172,9 @@ def collect(ctx: ReportContext) -> CamerasSection: ) flags["detect"] += camera.detect.enabled flags["record"] += camera.record.enabled - flags["sub_stream_record"] += camera.record.sub.enabled + flags["sub_stream_record"] += ( + camera.record.enabled and camera.record.sub.enabled + ) flags["snapshots"] += camera.snapshots.enabled flags["audio"] += camera.audio.enabled flags["audio_transcription"] += ( diff --git a/frigate/analytics/collectors/detection.py b/frigate/analytics/collectors/detection.py index d3939b80fd..f9155f38ec 100644 --- a/frigate/analytics/collectors/detection.py +++ b/frigate/analytics/collectors/detection.py @@ -32,6 +32,7 @@ def model_source(path: str | None) -> ModelSource: def collect(ctx: ReportContext) -> DetectionSection: + """Describe each configured model and its measured inference speed.""" config = ctx.config detectors = ctx.stats.get("detectors", {}) model_specs = [(model, config.devices_for_model(model)) for model in config.models] diff --git a/frigate/analytics/collectors/features.py b/frigate/analytics/collectors/features.py index 04164d3dcd..2f79738f51 100644 --- a/frigate/analytics/collectors/features.py +++ b/frigate/analytics/collectors/features.py @@ -86,6 +86,7 @@ def users() -> dict[UserRole, int]: def collect(ctx: ReportContext) -> FeaturesSection: + """Report which enrichments and integrations are configured.""" config = ctx.config devices = ctx.stats.get("embeddings", {}).get("devices", {}) cameras = [ diff --git a/frigate/analytics/collectors/hardware.py b/frigate/analytics/collectors/hardware.py index 48188ea122..a0ea9839da 100644 --- a/frigate/analytics/collectors/hardware.py +++ b/frigate/analytics/collectors/hardware.py @@ -96,6 +96,7 @@ def storage(stats: dict[str, Any]) -> StorageInfo: def collect(ctx: ReportContext) -> HardwareSection: + """Describe the host: CPU, memory, GPUs, decoders, detectors, storage.""" return HardwareSection( cpu_model=cpu_model(), cpu_cores=os.cpu_count() or 0, diff --git a/frigate/analytics/collectors/health.py b/frigate/analytics/collectors/health.py index 5fcf2b408c..3b8129fd7b 100644 --- a/frigate/analytics/collectors/health.py +++ b/frigate/analytics/collectors/health.py @@ -46,6 +46,7 @@ def notice_deltas(notice_stats: list[dict[str, Any]]) -> dict[Any, NoticeCounts] def collect(ctx: ReportContext) -> HealthSection: + """Read health figures from the latest stats and notice counts.""" service = ctx.stats.get("service", {}) embeddings = ctx.stats.get("embeddings", {}) cpu = ctx.stats.get("cpu_usages", {}).get("frigate.full_system", {}).get("cpu") diff --git a/frigate/analytics/collectors/install.py b/frigate/analytics/collectors/install.py index b4b86fccfa..c2b7a45eee 100644 --- a/frigate/analytics/collectors/install.py +++ b/frigate/analytics/collectors/install.py @@ -53,6 +53,7 @@ def kernel(release: str) -> str: def collect(ctx: ReportContext) -> InstallSection: + """Describe the Frigate version, image, install method, and platform.""" return InstallSection( version=VERSION[:32], image_variant=image_variant(os.environ.get("FRIGATE_IMAGE_VARIANT")), diff --git a/frigate/analytics/report.py b/frigate/analytics/report.py index e65c66ce44..d7d38835e8 100644 --- a/frigate/analytics/report.py +++ b/frigate/analytics/report.py @@ -70,6 +70,7 @@ def gather_context( stats_emitter: "StatsEmitter | None", notice_registry: "NoticeRegistry | None", ) -> ReportContext: + """Snapshot the config, latest stats, and notice counts for one report.""" return ReportContext( config=config, stats=stats_emitter.get_latest_stats() if stats_emitter is not None else {}, diff --git a/frigate/analytics/reporter.py b/frigate/analytics/reporter.py index a4c78d8c38..aeb571d532 100644 --- a/frigate/analytics/reporter.py +++ b/frigate/analytics/reporter.py @@ -105,6 +105,7 @@ class AnalyticsReporter(threading.Thread): delete_state(self.state_path) def tick(self) -> None: + """Apply consent and send a report when one is due.""" with self._lock: config = self.config_holder.config diff --git a/frigate/analytics/state.py b/frigate/analytics/state.py index ca2033d3f6..9e3154d4ec 100644 --- a/frigate/analytics/state.py +++ b/frigate/analytics/state.py @@ -22,6 +22,7 @@ class AnalyticsState: def new_state() -> AnalyticsState: + """A fresh install ID that has never attempted a report.""" return AnalyticsState(install_id=uuid4().hex, last_attempt_at=0.0) diff --git a/frigate/test/test_analytics_collectors_cameras.py b/frigate/test/test_analytics_collectors_cameras.py index 41b5a5fda8..300733adb0 100644 --- a/frigate/test/test_analytics_collectors_cameras.py +++ b/frigate/test/test_analytics_collectors_cameras.py @@ -51,7 +51,7 @@ CONFIG = { }, "audio": {"enabled": True}, "detect": {"height": 2160, "width": 3840, "fps": 15}, - "record": {"enabled": False}, + "record": {"enabled": False, "sub": {"enabled": True}}, }, "attic": { "enabled": False, @@ -95,6 +95,7 @@ class TestCamerasCollector(unittest.TestCase): self.assertEqual((section.zones, section.cameras_with_zones), (2, 1)) self.assertEqual((section.motion_masks, section.object_masks), (1, 2)) self.assertEqual((section.audio, section.audio_transcription), (1, 1)) + self.assertEqual(section.sub_stream_record, 0) self.assertEqual(section.connection_quality, {"excellent": 1}) def test_runtime_disabled_camera_skips_connection_quality(self): diff --git a/generate_analytics_schema.py b/generate_analytics_schema.py index eb276dd143..4b2f008ff5 100644 --- a/generate_analytics_schema.py +++ b/generate_analytics_schema.py @@ -30,6 +30,7 @@ def render() -> str: def main() -> int: + """Write or check the schema file; returns the process exit code.""" parser = argparse.ArgumentParser(description=__doc__.splitlines()[0]) parser.add_argument( "--check", action="store_true", help="fail if the committed schema is stale"