mirror of
https://github.com/blakeblackshear/frigate.git
synced 2026-09-26 07:38:59 +03:00
Add the analytics preview API
This commit is contained in:
Vendored
+19
@@ -10,6 +10,25 @@ servers:
|
||||
- url: https://demo.frigate.video/api
|
||||
- url: http://localhost:5001/api
|
||||
paths:
|
||||
/analytics/preview:
|
||||
get:
|
||||
tags:
|
||||
- Analytics
|
||||
summary: Get Analytics Preview
|
||||
description: |-
|
||||
**Access:** Admin role required.
|
||||
|
||||
Get the analytics report Frigate would send next, without sending it.
|
||||
operationId: get_analytics_preview_analytics_preview_get
|
||||
responses:
|
||||
'200':
|
||||
description: Successful Response
|
||||
content:
|
||||
application/json:
|
||||
schema: {}
|
||||
security:
|
||||
- frigateAdminAuth: []
|
||||
x-required-role: admin
|
||||
/auth/first_time_login:
|
||||
get:
|
||||
tags:
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
"""Analytics APIs."""
|
||||
|
||||
import logging
|
||||
|
||||
from fastapi import APIRouter, Depends, Request
|
||||
from fastapi.responses import JSONResponse
|
||||
|
||||
from frigate.analytics.report import preview_report
|
||||
from frigate.api.auth import require_role
|
||||
from frigate.api.defs.tags import Tags
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
router = APIRouter(tags=[Tags.analytics])
|
||||
|
||||
|
||||
@router.get("/analytics/preview", dependencies=[Depends(require_role(["admin"]))])
|
||||
def get_analytics_preview(request: Request) -> JSONResponse:
|
||||
"""Get the analytics report Frigate would send next, without sending it."""
|
||||
report = preview_report(
|
||||
request.app.frigate_config,
|
||||
request.app.stats_emitter,
|
||||
request.app.notice_registry,
|
||||
)
|
||||
return JSONResponse(content=report.model_dump(mode="json"))
|
||||
@@ -2,6 +2,7 @@ from enum import Enum
|
||||
|
||||
|
||||
class Tags(Enum):
|
||||
analytics = "Analytics"
|
||||
app = "App"
|
||||
auth = "Auth"
|
||||
camera = "Camera"
|
||||
|
||||
@@ -12,8 +12,8 @@ from slowapi.middleware import SlowAPIMiddleware
|
||||
from starlette_context import middleware, plugins
|
||||
from starlette_context.plugins import Plugin
|
||||
|
||||
from frigate.api import app as main_app
|
||||
from frigate.api import (
|
||||
analytics,
|
||||
auth,
|
||||
camera,
|
||||
chat,
|
||||
@@ -30,6 +30,7 @@ from frigate.api import (
|
||||
record,
|
||||
review,
|
||||
)
|
||||
from frigate.api import app as main_app
|
||||
from frigate.api.auth import get_jwt_secret, limiter, require_admin_by_default
|
||||
from frigate.comms.dispatcher import Dispatcher
|
||||
from frigate.comms.event_metadata_updater import (
|
||||
@@ -140,6 +141,7 @@ def create_fastapi_app(
|
||||
|
||||
# Routes
|
||||
# Order of include_router matters: https://fastapi.tiangolo.com/tutorial/path-params/#order-matters
|
||||
app.include_router(analytics.router)
|
||||
app.include_router(auth.router)
|
||||
app.include_router(camera.router)
|
||||
app.include_router(chat.router)
|
||||
|
||||
@@ -0,0 +1,49 @@
|
||||
"""Tests for the analytics preview API."""
|
||||
|
||||
from unittest.mock import Mock, patch
|
||||
|
||||
from frigate.analytics import report
|
||||
from frigate.analytics.collectors import hardware
|
||||
from frigate.models import Notice, NoticeStats, User
|
||||
from frigate.notices.registry import NoticeRegistry
|
||||
from frigate.test.http_api.base_http_test import AuthTestClient, BaseTestHttp
|
||||
|
||||
|
||||
class TestHttpAnalytics(BaseTestHttp):
|
||||
def setUp(self):
|
||||
super().setUp([Notice, NoticeStats, User])
|
||||
stats = Mock()
|
||||
stats.get_latest_stats.return_value = self.test_stats
|
||||
self.app = self.create_app(stats=stats, notice_registry=NoticeRegistry())
|
||||
|
||||
for target, name, value in (
|
||||
(report, "load_state", None),
|
||||
(hardware.hardware_prober, "probe", []),
|
||||
(hardware, "hwaccel_options", ("", [])),
|
||||
):
|
||||
patcher = patch.object(target, name, return_value=value)
|
||||
patcher.start()
|
||||
self.addCleanup(patcher.stop)
|
||||
|
||||
def test_preview_returns_the_report_without_sending_it(self):
|
||||
with (
|
||||
patch("frigate.analytics.transport.requests.post") as post,
|
||||
AuthTestClient(self.app) as client,
|
||||
):
|
||||
response = client.get("/analytics/preview")
|
||||
|
||||
self.assertEqual(response.status_code, 200)
|
||||
body = response.json()
|
||||
self.assertEqual(body["install_id"], report.PREVIEW_INSTALL_ID)
|
||||
self.assertEqual(body["schema_version"], 1)
|
||||
self.assertEqual(body["cameras"]["total"], 1)
|
||||
post.assert_not_called()
|
||||
|
||||
def test_preview_is_admin_only(self):
|
||||
with AuthTestClient(self.app) as client:
|
||||
response = client.get(
|
||||
"/analytics/preview",
|
||||
headers={"remote-user": "viewer", "remote-role": "viewer"},
|
||||
)
|
||||
|
||||
self.assertEqual(response.status_code, 403)
|
||||
@@ -47,8 +47,8 @@ from fastapi.routing import APIRoute
|
||||
from ruamel.yaml import YAML
|
||||
from ruamel.yaml.scalarstring import LiteralScalarString
|
||||
|
||||
from frigate.api import app as main_app
|
||||
from frigate.api import (
|
||||
analytics,
|
||||
auth,
|
||||
camera,
|
||||
chat,
|
||||
@@ -65,6 +65,7 @@ from frigate.api import (
|
||||
record,
|
||||
review,
|
||||
)
|
||||
from frigate.api import app as main_app
|
||||
from frigate.api.auth import require_admin_by_default
|
||||
|
||||
logging.basicConfig(level=logging.INFO, format="%(message)s")
|
||||
@@ -145,6 +146,7 @@ def build_app() -> FastAPI:
|
||||
"""
|
||||
app = FastAPI()
|
||||
routers = [
|
||||
analytics.router,
|
||||
auth.router,
|
||||
camera.router,
|
||||
chat.router,
|
||||
|
||||
Reference in New Issue
Block a user