From 1a5f7079987cfb40b5f83da51cc48499f2089301 Mon Sep 17 00:00:00 2001 From: Josh Hawkins <32435876+hawkeye217@users.noreply.github.com> Date: Tue, 24 Sep 2024 08:38:04 -0500 Subject: [PATCH] fix fastapi --- frigate/api/fastapi_app.py | 5 ++ frigate/test/test_http.py | 125 ++++++++++++++++++------------------- 2 files changed, 67 insertions(+), 63 deletions(-) diff --git a/frigate/api/fastapi_app.py b/frigate/api/fastapi_app.py index 39f8d0f65..fb6e4df0b 100644 --- a/frigate/api/fastapi_app.py +++ b/frigate/api/fastapi_app.py @@ -13,6 +13,9 @@ from starlette_context.plugins import Plugin from frigate.api import app as main_app from frigate.api import auth, event, export, media, notification, preview, review from frigate.api.auth import get_jwt_secret, limiter +from frigate.comms.event_metadata_updater import ( + EventMetadataPublisher, +) from frigate.config import FrigateConfig from frigate.embeddings import EmbeddingsContext from frigate.events.external import ExternalEventProcessor @@ -47,6 +50,7 @@ def create_fastapi_app( onvif: OnvifController, external_processor: ExternalEventProcessor, stats_emitter: StatsEmitter, + event_metadata_updater: EventMetadataPublisher, ): logger.info("Starting FastAPI app") app = FastAPI( @@ -102,6 +106,7 @@ def create_fastapi_app( app.camera_error_image = None app.onvif = onvif app.stats_emitter = stats_emitter + app.event_metadata_updater = event_metadata_updater app.external_processor = external_processor app.jwt_token = get_jwt_secret() if frigate_config.auth.enabled else None diff --git a/frigate/test/test_http.py b/frigate/test/test_http.py index d5927ad2b..063f154ea 100644 --- a/frigate/test/test_http.py +++ b/frigate/test/test_http.py @@ -1,18 +1,18 @@ import datetime +import json import logging import os import unittest from unittest.mock import Mock -from fastapi.testclient import TestClient from peewee_migrate import Router from playhouse.shortcuts import model_to_dict from playhouse.sqlite_ext import SqliteExtDatabase from playhouse.sqliteq import SqliteQueueDatabase -from frigate.api.fastapi_app import create_fastapi_app +from frigate.api.app import create_app from frigate.config import FrigateConfig -from frigate.models import Event, Recordings, Timeline +from frigate.models import Event, Recordings from frigate.stats.emitter import StatsEmitter from frigate.test.const import TEST_DB, TEST_DB_CLEANUPS @@ -26,7 +26,7 @@ class TestHttp(unittest.TestCase): router.run() migrate_db.close() self.db = SqliteQueueDatabase(TEST_DB) - models = [Event, Recordings, Timeline] + models = [Event, Recordings] self.db.bind(models) self.minimal_config = { @@ -112,7 +112,7 @@ class TestHttp(unittest.TestCase): pass def test_get_event_list(self): - app = create_fastapi_app( + app = create_app( FrigateConfig(**self.minimal_config), self.db, None, @@ -126,30 +126,30 @@ class TestHttp(unittest.TestCase): id = "123456.random" id2 = "7890.random" - with TestClient(app) as client: + with app.test_client() as client: _insert_mock_event(id) - events = client.get("/events").json() + events = client.get("/events").json assert events assert len(events) == 1 assert events[0]["id"] == id _insert_mock_event(id2) - events = client.get("/events").json() + events = client.get("/events").json assert events assert len(events) == 2 events = client.get( "/events", - params={"limit": 1}, - ).json() + query_string={"limit": 1}, + ).json assert events assert len(events) == 1 events = client.get( "/events", - params={"has_clip": 0}, - ).json() + query_string={"has_clip": 0}, + ).json assert not events def test_get_good_event(self): - app = create_fastapi_app( + app = create_app( FrigateConfig(**self.minimal_config), self.db, None, @@ -162,16 +162,16 @@ class TestHttp(unittest.TestCase): ) id = "123456.random" - with TestClient(app) as client: + with app.test_client() as client: _insert_mock_event(id) - event = client.get(f"/events/{id}").json() + event = client.get(f"/events/{id}").json assert event assert event["id"] == id assert event == model_to_dict(Event.get(Event.id == id)) def test_get_bad_event(self): - app = create_fastapi_app( + app = create_app( FrigateConfig(**self.minimal_config), self.db, None, @@ -185,14 +185,14 @@ class TestHttp(unittest.TestCase): id = "123456.random" bad_id = "654321.other" - with TestClient(app) as client: + with app.test_client() as client: _insert_mock_event(id) - event_response = client.get(f"/events/{bad_id}") - assert event_response.status_code == 404 - assert event_response.json() == "Event not found" + event = client.get(f"/events/{bad_id}").json + + assert not event def test_delete_event(self): - app = create_fastapi_app( + app = create_app( FrigateConfig(**self.minimal_config), self.db, None, @@ -205,17 +205,17 @@ class TestHttp(unittest.TestCase): ) id = "123456.random" - with TestClient(app) as client: + with app.test_client() as client: _insert_mock_event(id) - event = client.get(f"/events/{id}").json() + event = client.get(f"/events/{id}").json assert event assert event["id"] == id client.delete(f"/events/{id}") - event = client.get(f"/events/{id}").json() - assert event == "Event not found" + event = client.get(f"/events/{id}").json + assert not event def test_event_retention(self): - app = create_fastapi_app( + app = create_app( FrigateConfig(**self.minimal_config), self.db, None, @@ -228,21 +228,21 @@ class TestHttp(unittest.TestCase): ) id = "123456.random" - with TestClient(app) as client: + with app.test_client() as client: _insert_mock_event(id) client.post(f"/events/{id}/retain") - event = client.get(f"/events/{id}").json() + event = client.get(f"/events/{id}").json assert event assert event["id"] == id assert event["retain_indefinitely"] is True client.delete(f"/events/{id}/retain") - event = client.get(f"/events/{id}").json() + event = client.get(f"/events/{id}").json assert event assert event["id"] == id assert event["retain_indefinitely"] is False def test_event_time_filtering(self): - app = create_fastapi_app( + app = create_app( FrigateConfig(**self.minimal_config), self.db, None, @@ -258,30 +258,30 @@ class TestHttp(unittest.TestCase): morning = 1656590400 # 06/30/2022 6 am (GMT) evening = 1656633600 # 06/30/2022 6 pm (GMT) - with TestClient(app) as client: + with app.test_client() as client: _insert_mock_event(morning_id, morning) _insert_mock_event(evening_id, evening) # both events come back - events = client.get("/events").json() + events = client.get("/events").json assert events assert len(events) == 2 # morning event is excluded events = client.get( "/events", - params={"time_range": "07:00,24:00"}, - ).json() + query_string={"time_range": "07:00,24:00"}, + ).json assert events # assert len(events) == 1 # evening event is excluded events = client.get( "/events", - params={"time_range": "00:00,18:00"}, - ).json() + query_string={"time_range": "00:00,18:00"}, + ).json assert events assert len(events) == 1 def test_set_delete_sub_label(self): - app = create_fastapi_app( + app = create_app( FrigateConfig(**self.minimal_config), self.db, None, @@ -295,29 +295,29 @@ class TestHttp(unittest.TestCase): id = "123456.random" sub_label = "sub" - with TestClient(app) as client: + with app.test_client() as client: _insert_mock_event(id) - new_sub_label_response = client.post( + client.post( f"/events/{id}/sub_label", - json={"subLabel": sub_label}, + data=json.dumps({"subLabel": sub_label}), + content_type="application/json", ) - assert new_sub_label_response.status_code == 200 - event = client.get(f"/events/{id}").json() + event = client.get(f"/events/{id}").json assert event assert event["id"] == id assert event["sub_label"] == sub_label - empty_sub_label_response = client.post( + client.post( f"/events/{id}/sub_label", - json={"subLabel": ""}, + data=json.dumps({"subLabel": ""}), + content_type="application/json", ) - assert empty_sub_label_response.status_code == 200 - event = client.get(f"/events/{id}").json() + event = client.get(f"/events/{id}").json assert event assert event["id"] == id assert event["sub_label"] == "" def test_sub_label_list(self): - app = create_fastapi_app( + app = create_app( FrigateConfig(**self.minimal_config), self.db, None, @@ -331,18 +331,19 @@ class TestHttp(unittest.TestCase): id = "123456.random" sub_label = "sub" - with TestClient(app) as client: + with app.test_client() as client: _insert_mock_event(id) client.post( f"/events/{id}/sub_label", - json={"subLabel": sub_label}, + data=json.dumps({"subLabel": sub_label}), + content_type="application/json", ) - sub_labels = client.get("/sub_labels").json() + sub_labels = client.get("/sub_labels").json assert sub_labels assert sub_labels == [sub_label] def test_config(self): - app = create_fastapi_app( + app = create_app( FrigateConfig(**self.minimal_config), self.db, None, @@ -354,13 +355,13 @@ class TestHttp(unittest.TestCase): None, ) - with TestClient(app) as client: - config = client.get("/config").json() + with app.test_client() as client: + config = client.get("/config").json assert config assert config["cameras"]["front_door"] def test_recordings(self): - app = create_fastapi_app( + app = create_app( FrigateConfig(**self.minimal_config), self.db, None, @@ -373,18 +374,16 @@ class TestHttp(unittest.TestCase): ) id = "123456.random" - with TestClient(app) as client: + with app.test_client() as client: _insert_mock_recording(id) - response = client.get("/front_door/recordings") - assert response.status_code == 200 - recording = response.json() + recording = client.get("/front_door/recordings").json assert recording assert recording[0]["id"] == id def test_stats(self): stats = Mock(spec=StatsEmitter) stats.get_latest_stats.return_value = self.test_stats - app = create_fastapi_app( + app = create_app( FrigateConfig(**self.minimal_config), self.db, None, @@ -396,8 +395,8 @@ class TestHttp(unittest.TestCase): None, ) - with TestClient(app) as client: - full_stats = client.get("/stats").json() + with app.test_client() as client: + full_stats = client.get("/stats").json assert full_stats == self.test_stats @@ -430,8 +429,8 @@ def _insert_mock_recording(id: str) -> Event: id=id, camera="front_door", path=f"/recordings/{id}", - start_time=datetime.datetime.now().timestamp() - 60, - end_time=datetime.datetime.now().timestamp() - 50, + start_time=datetime.datetime.now().timestamp() - 50, + end_time=datetime.datetime.now().timestamp() - 60, duration=10, motion=True, objects=True,