From 1959d249081a229b63ac509ae0ab6856d8b1a9d6 Mon Sep 17 00:00:00 2001 From: George Tsiamasiotis Date: Sat, 21 Sep 2024 13:24:02 +0300 Subject: [PATCH] Automatically call FrigateConfig.runtime_config() runtime_config needed to be called manually before. Now, it's been removed, but the same code is run by a pydantic validator. --- frigate/api/app.py | 4 +- frigate/app.py | 3 +- frigate/config.py | 78 +++---- frigate/test/test_config.py | 323 ++++++++++------------------ frigate/test/test_ffmpeg_presets.py | 14 +- frigate/test/test_http.py | 6 +- process_clip.py | 5 +- 7 files changed, 163 insertions(+), 270 deletions(-) diff --git a/frigate/api/app.py b/frigate/api/app.py index c841d7c2d..889bbea74 100644 --- a/frigate/api/app.py +++ b/frigate/api/app.py @@ -361,8 +361,8 @@ def config_set(): json = request.get_json(silent=True) or {} if json.get("requires_restart", 1) == 0: - current_app.frigate_config = FrigateConfig.runtime_config( - config_obj, current_app.plus_api + current_app.frigate_config = FrigateConfig.parse_object( + config_obj, plus_api=current_app.plus_api ) return make_response( diff --git a/frigate/app.py b/frigate/app.py index 0059cbfe2..f6479d9ad 100644 --- a/frigate/app.py +++ b/frigate/app.py @@ -129,8 +129,7 @@ class FrigateApp: # check if the config file needs to be migrated migrate_frigate_config(config_file) - user_config = FrigateConfig.parse_file(config_file) - self.config = user_config.runtime_config(self.plus_api) + self.config = FrigateConfig.parse_file(config_file, plus_api=self.plus_api) for camera_name in self.config.cameras.keys(): # create camera_metrics diff --git a/frigate/config.py b/frigate/config.py index ccbf2ac83..42209858b 100644 --- a/frigate/config.py +++ b/frigate/config.py @@ -18,6 +18,7 @@ from pydantic import ( ValidationInfo, field_serializer, field_validator, + model_validator, ) from pydantic.fields import PrivateAttr from ruamel.yaml import YAML @@ -44,7 +45,6 @@ from frigate.ffmpeg_presets import ( parse_preset_input, parse_preset_output_record, ) -from frigate.plus import PlusApi from frigate.util.builtin import ( deep_merge, escape_special_characters, @@ -1494,26 +1494,28 @@ class FrigateConfig(FrigateBaseModel): ) version: Optional[str] = Field(default=None, title="Current config version.") - def runtime_config(self, plus_api: PlusApi = None) -> FrigateConfig: - """Merge camera config with globals.""" - config = self.model_copy(deep=True) + @model_validator(mode="after") + def post_validation(self, info: ValidationInfo) -> Self: + plus_api = None + if isinstance(info.context, dict): + plus_api = info.context.get("plus_api") # set notifications state - config.notifications.enabled_in_config = config.notifications.enabled + self.notifications.enabled_in_config = self.notifications.enabled # set default min_score for object attributes for attribute in ALL_ATTRIBUTE_LABELS: - if not config.objects.filters.get(attribute): - config.objects.filters[attribute] = FilterConfig(min_score=0.7) - elif config.objects.filters[attribute].min_score == 0.5: - config.objects.filters[attribute].min_score = 0.7 + if not self.objects.filters.get(attribute): + self.objects.filters[attribute] = FilterConfig(min_score=0.7) + elif self.objects.filters[attribute].min_score == 0.5: + self.objects.filters[attribute].min_score = 0.7 # auto detect hwaccel args - if config.ffmpeg.hwaccel_args == "auto": - config.ffmpeg.hwaccel_args = auto_detect_hwaccel() + if self.ffmpeg.hwaccel_args == "auto": + self.ffmpeg.hwaccel_args = auto_detect_hwaccel() # Global config to propagate down to camera level - global_config = config.model_dump( + global_config = self.model_dump( include={ "audio": ..., "birdseye": ..., @@ -1531,7 +1533,7 @@ class FrigateConfig(FrigateBaseModel): exclude_unset=True, ) - for name, camera in config.cameras.items(): + for name, camera in self.cameras.items(): merged_config = deep_merge( camera.model_dump(exclude_unset=True), global_config ) @@ -1540,7 +1542,7 @@ class FrigateConfig(FrigateBaseModel): ) if camera_config.ffmpeg.hwaccel_args == "auto": - camera_config.ffmpeg.hwaccel_args = config.ffmpeg.hwaccel_args + camera_config.ffmpeg.hwaccel_args = self.ffmpeg.hwaccel_args for input in camera_config.ffmpeg.inputs: need_record_fourcc = False and "record" in input.roles @@ -1553,7 +1555,7 @@ class FrigateConfig(FrigateBaseModel): stream_info = {"width": 0, "height": 0, "fourcc": None} try: stream_info = stream_info_retriever.get_stream_info( - config.ffmpeg, input.path + self.ffmpeg, input.path ) except Exception: logger.warn( @@ -1671,8 +1673,12 @@ class FrigateConfig(FrigateBaseModel): if not camera_config.live.stream_name: camera_config.live.stream_name = name + # generate the ffmpeg commands + camera_config.create_ffmpeg_cmds() + self.cameras[name] = camera_config + verify_config_roles(camera_config) - verify_valid_live_stream_name(config, camera_config) + verify_valid_live_stream_name(self, camera_config) verify_recording_retention(camera_config) verify_recording_segments_setup_with_reasonable_time(camera_config) verify_zone_objects_are_tracked(camera_config) @@ -1680,20 +1686,16 @@ class FrigateConfig(FrigateBaseModel): verify_autotrack_zones(camera_config) verify_motion_and_detect(camera_config) - # generate the ffmpeg commands - camera_config.create_ffmpeg_cmds() - config.cameras[name] = camera_config - # get list of unique enabled labels for tracking - enabled_labels = set(config.objects.track) + enabled_labels = set(self.objects.track) - for _, camera in config.cameras.items(): + for camera in self.cameras.values(): enabled_labels.update(camera.objects.track) - config.model.create_colormap(sorted(enabled_labels)) - config.model.check_and_load_plus_model(plus_api) + self.model.create_colormap(sorted(enabled_labels)) + self.model.check_and_load_plus_model(plus_api) - for key, detector in config.detectors.items(): + for key, detector in self.detectors.items(): adapter = TypeAdapter(DetectorConfig) model_dict = ( detector @@ -1702,10 +1704,10 @@ class FrigateConfig(FrigateBaseModel): ) detector_config: DetectorConfig = adapter.validate_python(model_dict) if detector_config.model is None: - detector_config.model = config.model.model_copy() + detector_config.model = self.model.model_copy() else: path = detector_config.model.path - detector_config.model = config.model.model_copy() + detector_config.model = self.model.model_copy() detector_config.model.path = path if "path" not in model_dict or len(model_dict.keys()) > 1: @@ -1715,7 +1717,7 @@ class FrigateConfig(FrigateBaseModel): merged_model = deep_merge( detector_config.model.model_dump(exclude_unset=True, warnings="none"), - config.model.model_dump(exclude_unset=True, warnings="none"), + self.model.model_dump(exclude_unset=True, warnings="none"), ) if "path" not in merged_model: @@ -1729,9 +1731,9 @@ class FrigateConfig(FrigateBaseModel): plus_api, detector_config.type ) detector_config.model.compute_model_hash() - config.detectors[key] = detector_config + self.detectors[key] = detector_config - return config + return self @field_validator("cameras") @classmethod @@ -1743,12 +1745,12 @@ class FrigateConfig(FrigateBaseModel): return v @classmethod - def parse_file(cls, config_path, *, is_json=None) -> Self: + def parse_file(cls, config_path, **kwargs) -> Self: with open(config_path) as f: - return FrigateConfig.parse(f, is_json=is_json) + return FrigateConfig.parse(f, **kwargs) @classmethod - def parse(cls, config, *, is_json=None) -> Self: + def parse(cls, config, *, is_json=None, **context) -> Self: # If config is a file, read its contents. if hasattr(config, "read"): fname = getattr(config, "name", None) @@ -1773,8 +1775,12 @@ class FrigateConfig(FrigateBaseModel): config = yaml.load(config) # Validate and return the config dict. - return cls.model_validate(config) + return cls.parse_object(config, **context) @classmethod - def parse_yaml(cls, config_yaml) -> Self: - return cls.parse(config_yaml, is_json=False) + def parse_object(cls, obj: Any, **context): + return cls.model_validate(obj, context=context) + + @classmethod + def parse_yaml(cls, config_yaml, **context) -> Self: + return cls.parse(config_yaml, is_json=False, **context) diff --git a/frigate/test/test_config.py b/frigate/test/test_config.py index 5191d3551..143609386 100644 --- a/frigate/test/test_config.py +++ b/frigate/test/test_config.py @@ -10,7 +10,6 @@ from ruamel.yaml.constructor import DuplicateKeyError from frigate.config import BirdseyeModeEnum, FrigateConfig from frigate.const import MODEL_CACHE_DIR from frigate.detectors import DetectorTypeEnum -from frigate.plus import PlusApi from frigate.util.builtin import deep_merge @@ -65,12 +64,9 @@ class TestConfig(unittest.TestCase): def test_config_class(self): frigate_config = FrigateConfig(**self.minimal) - assert self.minimal == frigate_config.model_dump(exclude_unset=True) - - runtime_config = frigate_config.runtime_config() - assert "cpu" in runtime_config.detectors.keys() - assert runtime_config.detectors["cpu"].type == DetectorTypeEnum.cpu - assert runtime_config.detectors["cpu"].model.width == 320 + assert "cpu" in frigate_config.detectors.keys() + assert frigate_config.detectors["cpu"].type == DetectorTypeEnum.cpu + assert frigate_config.detectors["cpu"].model.width == 320 @patch("frigate.detectors.detector_config.load_labels") def test_detector_custom_model_path(self, mock_labels): @@ -94,24 +90,23 @@ class TestConfig(unittest.TestCase): } frigate_config = FrigateConfig(**(deep_merge(config, self.minimal))) - runtime_config = frigate_config.runtime_config() - assert "cpu" in runtime_config.detectors.keys() - assert "edgetpu" in runtime_config.detectors.keys() - assert "openvino" in runtime_config.detectors.keys() + assert "cpu" in frigate_config.detectors.keys() + assert "edgetpu" in frigate_config.detectors.keys() + assert "openvino" in frigate_config.detectors.keys() - assert runtime_config.detectors["cpu"].type == DetectorTypeEnum.cpu - assert runtime_config.detectors["edgetpu"].type == DetectorTypeEnum.edgetpu - assert runtime_config.detectors["openvino"].type == DetectorTypeEnum.openvino + assert frigate_config.detectors["cpu"].type == DetectorTypeEnum.cpu + assert frigate_config.detectors["edgetpu"].type == DetectorTypeEnum.edgetpu + assert frigate_config.detectors["openvino"].type == DetectorTypeEnum.openvino - assert runtime_config.detectors["cpu"].num_threads == 3 - assert runtime_config.detectors["edgetpu"].device is None - assert runtime_config.detectors["openvino"].device is None + assert frigate_config.detectors["cpu"].num_threads == 3 + assert frigate_config.detectors["edgetpu"].device is None + assert frigate_config.detectors["openvino"].device is None - assert runtime_config.model.path == "/etc/hosts" - assert runtime_config.detectors["cpu"].model.path == "/cpu_model.tflite" - assert runtime_config.detectors["edgetpu"].model.path == "/edgetpu_model.tflite" - assert runtime_config.detectors["openvino"].model.path == "/etc/hosts" + assert frigate_config.model.path == "/etc/hosts" + assert frigate_config.detectors["cpu"].model.path == "/cpu_model.tflite" + assert frigate_config.detectors["edgetpu"].model.path == "/edgetpu_model.tflite" + assert frigate_config.detectors["openvino"].model.path == "/etc/hosts" def test_invalid_mqtt_config(self): config = { @@ -152,11 +147,9 @@ class TestConfig(unittest.TestCase): } }, } - frigate_config = FrigateConfig(**config) - assert config == frigate_config.model_dump(exclude_unset=True) - runtime_config = frigate_config.runtime_config() - assert "dog" in runtime_config.cameras["back"].objects.track + frigate_config = FrigateConfig(**config) + assert "dog" in frigate_config.cameras["back"].objects.track def test_override_birdseye(self): config = { @@ -178,12 +171,10 @@ class TestConfig(unittest.TestCase): } }, } - frigate_config = FrigateConfig(**config) - assert config == frigate_config.model_dump(exclude_unset=True) - runtime_config = frigate_config.runtime_config() - assert not runtime_config.cameras["back"].birdseye.enabled - assert runtime_config.cameras["back"].birdseye.mode is BirdseyeModeEnum.motion + frigate_config = FrigateConfig(**config) + assert not frigate_config.cameras["back"].birdseye.enabled + assert frigate_config.cameras["back"].birdseye.mode is BirdseyeModeEnum.motion def test_override_birdseye_non_inheritable(self): config = { @@ -204,11 +195,9 @@ class TestConfig(unittest.TestCase): } }, } - frigate_config = FrigateConfig(**config) - assert config == frigate_config.model_dump(exclude_unset=True) - runtime_config = frigate_config.runtime_config() - assert runtime_config.cameras["back"].birdseye.enabled + frigate_config = FrigateConfig(**config) + assert frigate_config.cameras["back"].birdseye.enabled def test_inherit_birdseye(self): config = { @@ -229,13 +218,11 @@ class TestConfig(unittest.TestCase): } }, } - frigate_config = FrigateConfig(**config) - assert config == frigate_config.model_dump(exclude_unset=True) - runtime_config = frigate_config.runtime_config() - assert runtime_config.cameras["back"].birdseye.enabled + frigate_config = FrigateConfig(**config) + assert frigate_config.cameras["back"].birdseye.enabled assert ( - runtime_config.cameras["back"].birdseye.mode is BirdseyeModeEnum.continuous + frigate_config.cameras["back"].birdseye.mode is BirdseyeModeEnum.continuous ) def test_override_tracked_objects(self): @@ -258,11 +245,9 @@ class TestConfig(unittest.TestCase): } }, } - frigate_config = FrigateConfig(**config) - assert config == frigate_config.model_dump(exclude_unset=True) - runtime_config = frigate_config.runtime_config() - assert "cat" in runtime_config.cameras["back"].objects.track + frigate_config = FrigateConfig(**config) + assert "cat" in frigate_config.cameras["back"].objects.track def test_default_object_filters(self): config = { @@ -283,11 +268,9 @@ class TestConfig(unittest.TestCase): } }, } - frigate_config = FrigateConfig(**config) - assert config == frigate_config.model_dump(exclude_unset=True) - runtime_config = frigate_config.runtime_config() - assert "dog" in runtime_config.cameras["back"].objects.filters + frigate_config = FrigateConfig(**config) + assert "dog" in frigate_config.cameras["back"].objects.filters def test_inherit_object_filters(self): config = { @@ -311,12 +294,10 @@ class TestConfig(unittest.TestCase): } }, } - frigate_config = FrigateConfig(**config) - assert config == frigate_config.model_dump(exclude_unset=True) - runtime_config = frigate_config.runtime_config() - assert "dog" in runtime_config.cameras["back"].objects.filters - assert runtime_config.cameras["back"].objects.filters["dog"].threshold == 0.7 + frigate_config = FrigateConfig(**config) + assert "dog" in frigate_config.cameras["back"].objects.filters + assert frigate_config.cameras["back"].objects.filters["dog"].threshold == 0.7 def test_override_object_filters(self): config = { @@ -340,12 +321,10 @@ class TestConfig(unittest.TestCase): } }, } - frigate_config = FrigateConfig(**config) - assert config == frigate_config.model_dump(exclude_unset=True) - runtime_config = frigate_config.runtime_config() - assert "dog" in runtime_config.cameras["back"].objects.filters - assert runtime_config.cameras["back"].objects.filters["dog"].threshold == 0.7 + frigate_config = FrigateConfig(**config) + assert "dog" in frigate_config.cameras["back"].objects.filters + assert frigate_config.cameras["back"].objects.filters["dog"].threshold == 0.7 def test_global_object_mask(self): config = { @@ -370,11 +349,9 @@ class TestConfig(unittest.TestCase): } }, } - frigate_config = FrigateConfig(**config) - assert config == frigate_config.model_dump(exclude_unset=True) - runtime_config = frigate_config.runtime_config() - back_camera = runtime_config.cameras["back"] + frigate_config = FrigateConfig(**config) + back_camera = frigate_config.cameras["back"] assert "dog" in back_camera.objects.filters assert len(back_camera.objects.filters["dog"].raw_mask) == 2 assert len(back_camera.objects.filters["person"].raw_mask) == 1 @@ -420,7 +397,8 @@ class TestConfig(unittest.TestCase): }, }, } - frigate_config = FrigateConfig(**config).runtime_config() + + frigate_config = FrigateConfig(**config) assert np.array_equal( frigate_config.cameras["explicit"].motion.mask, frigate_config.cameras["relative"].motion.mask, @@ -449,10 +427,7 @@ class TestConfig(unittest.TestCase): } frigate_config = FrigateConfig(**config) - assert config == frigate_config.model_dump(exclude_unset=True) - - runtime_config = frigate_config.runtime_config() - assert "-rtsp_transport" in runtime_config.cameras["back"].ffmpeg_cmds[0]["cmd"] + assert "-rtsp_transport" in frigate_config.cameras["back"].ffmpeg_cmds[0]["cmd"] def test_ffmpeg_params_global(self): config = { @@ -477,11 +452,9 @@ class TestConfig(unittest.TestCase): } }, } - frigate_config = FrigateConfig(**config) - assert config == frigate_config.model_dump(exclude_unset=True) - runtime_config = frigate_config.runtime_config() - assert "-re" in runtime_config.cameras["back"].ffmpeg_cmds[0]["cmd"] + frigate_config = FrigateConfig(**config) + assert "-re" in frigate_config.cameras["back"].ffmpeg_cmds[0]["cmd"] def test_ffmpeg_params_camera(self): config = { @@ -507,12 +480,10 @@ class TestConfig(unittest.TestCase): } }, } - frigate_config = FrigateConfig(**config) - assert config == frigate_config.model_dump(exclude_unset=True) - runtime_config = frigate_config.runtime_config() - assert "-re" in runtime_config.cameras["back"].ffmpeg_cmds[0]["cmd"] - assert "test" not in runtime_config.cameras["back"].ffmpeg_cmds[0]["cmd"] + frigate_config = FrigateConfig(**config) + assert "-re" in frigate_config.cameras["back"].ffmpeg_cmds[0]["cmd"] + assert "test" not in frigate_config.cameras["back"].ffmpeg_cmds[0]["cmd"] def test_ffmpeg_params_input(self): config = { @@ -542,14 +513,12 @@ class TestConfig(unittest.TestCase): } }, } - frigate_config = FrigateConfig(**config) - assert config == frigate_config.model_dump(exclude_unset=True) - runtime_config = frigate_config.runtime_config() - assert "-re" in runtime_config.cameras["back"].ffmpeg_cmds[0]["cmd"] - assert "test" in runtime_config.cameras["back"].ffmpeg_cmds[0]["cmd"] - assert "test2" not in runtime_config.cameras["back"].ffmpeg_cmds[0]["cmd"] - assert "test3" not in runtime_config.cameras["back"].ffmpeg_cmds[0]["cmd"] + frigate_config = FrigateConfig(**config) + assert "-re" in frigate_config.cameras["back"].ffmpeg_cmds[0]["cmd"] + assert "test" in frigate_config.cameras["back"].ffmpeg_cmds[0]["cmd"] + assert "test2" not in frigate_config.cameras["back"].ffmpeg_cmds[0]["cmd"] + assert "test3" not in frigate_config.cameras["back"].ffmpeg_cmds[0]["cmd"] def test_inherit_clips_retention(self): config = { @@ -570,11 +539,9 @@ class TestConfig(unittest.TestCase): } }, } - frigate_config = FrigateConfig(**config) - assert config == frigate_config.model_dump(exclude_unset=True) - runtime_config = frigate_config.runtime_config() - assert runtime_config.cameras["back"].record.alerts.retain.days == 20 + frigate_config = FrigateConfig(**config) + assert frigate_config.cameras["back"].record.alerts.retain.days == 20 def test_roles_listed_twice_throws_error(self): config = { @@ -658,14 +625,12 @@ class TestConfig(unittest.TestCase): } }, } - frigate_config = FrigateConfig(**config) - assert config == frigate_config.model_dump(exclude_unset=True) - runtime_config = frigate_config.runtime_config() + frigate_config = FrigateConfig(**config) assert isinstance( - runtime_config.cameras["back"].zones["test"].contour, np.ndarray + frigate_config.cameras["back"].zones["test"].contour, np.ndarray ) - assert runtime_config.cameras["back"].zones["test"].color != (0, 0, 0) + assert frigate_config.cameras["back"].zones["test"].color != (0, 0, 0) def test_zone_relative_matches_explicit(self): config = { @@ -700,7 +665,8 @@ class TestConfig(unittest.TestCase): } }, } - frigate_config = FrigateConfig(**config).runtime_config() + + frigate_config = FrigateConfig(**config) assert np.array_equal( frigate_config.cameras["back"].zones["explicit"].contour, frigate_config.cameras["back"].zones["relative"].contour, @@ -730,10 +696,7 @@ class TestConfig(unittest.TestCase): } frigate_config = FrigateConfig(**config) - assert config == frigate_config.model_dump(exclude_unset=True) - - runtime_config = frigate_config.runtime_config() - ffmpeg_cmds = runtime_config.cameras["back"].ffmpeg_cmds + ffmpeg_cmds = frigate_config.cameras["back"].ffmpeg_cmds assert len(ffmpeg_cmds) == 1 assert "clips" not in ffmpeg_cmds[0]["roles"] @@ -761,10 +724,7 @@ class TestConfig(unittest.TestCase): } frigate_config = FrigateConfig(**config) - assert config == frigate_config.model_dump(exclude_unset=True) - - runtime_config = frigate_config.runtime_config() - assert runtime_config.cameras["back"].detect.max_disappeared == 5 * 5 + assert frigate_config.cameras["back"].detect.max_disappeared == 5 * 5 def test_motion_frame_height_wont_go_below_120(self): config = { @@ -789,10 +749,7 @@ class TestConfig(unittest.TestCase): } frigate_config = FrigateConfig(**config) - assert config == frigate_config.model_dump(exclude_unset=True) - - runtime_config = frigate_config.runtime_config() - assert runtime_config.cameras["back"].motion.frame_height == 100 + assert frigate_config.cameras["back"].motion.frame_height == 100 def test_motion_contour_area_dynamic(self): config = { @@ -817,10 +774,7 @@ class TestConfig(unittest.TestCase): } frigate_config = FrigateConfig(**config) - assert config == frigate_config.model_dump(exclude_unset=True) - - runtime_config = frigate_config.runtime_config() - assert round(runtime_config.cameras["back"].motion.contour_area) == 10 + assert round(frigate_config.cameras["back"].motion.contour_area) == 10 def test_merge_labelmap(self): config = { @@ -846,10 +800,7 @@ class TestConfig(unittest.TestCase): } frigate_config = FrigateConfig(**config) - assert config == frigate_config.model_dump(exclude_unset=True) - - runtime_config = frigate_config.runtime_config() - assert runtime_config.model.merged_labelmap[7] == "truck" + assert frigate_config.model.merged_labelmap[7] == "truck" def test_default_labelmap_empty(self): config = { @@ -874,10 +825,7 @@ class TestConfig(unittest.TestCase): } frigate_config = FrigateConfig(**config) - assert config == frigate_config.model_dump(exclude_unset=True) - - runtime_config = frigate_config.runtime_config() - assert runtime_config.model.merged_labelmap[0] == "person" + assert frigate_config.model.merged_labelmap[0] == "person" def test_default_labelmap(self): config = { @@ -903,10 +851,7 @@ class TestConfig(unittest.TestCase): } frigate_config = FrigateConfig(**config) - assert config == frigate_config.model_dump(exclude_unset=True) - - runtime_config = frigate_config.runtime_config() - assert runtime_config.model.merged_labelmap[0] == "person" + assert frigate_config.model.merged_labelmap[0] == "person" def test_plus_labelmap(self): with open("/config/model_cache/test", "w") as f: @@ -937,10 +882,7 @@ class TestConfig(unittest.TestCase): } frigate_config = FrigateConfig(**config) - assert config == frigate_config.model_dump(exclude_unset=True) - - runtime_config = frigate_config.runtime_config(PlusApi()) - assert runtime_config.model.merged_labelmap[0] == "amazon" + assert frigate_config.model.merged_labelmap[0] == "amazon" def test_fails_on_invalid_role(self): config = { @@ -997,8 +939,7 @@ class TestConfig(unittest.TestCase): }, } - frigate_config = FrigateConfig(**config) - self.assertRaises(ValueError, lambda: frigate_config.runtime_config()) + self.assertRaises(ValueError, lambda: FrigateConfig(**config)) def test_works_on_missing_role_multiple_cams(self): config = { @@ -1045,8 +986,7 @@ class TestConfig(unittest.TestCase): }, } - frigate_config = FrigateConfig(**config) - frigate_config.runtime_config() + FrigateConfig(**config) def test_global_detect(self): config = { @@ -1070,12 +1010,10 @@ class TestConfig(unittest.TestCase): } }, } - frigate_config = FrigateConfig(**config) - assert config == frigate_config.model_dump(exclude_unset=True) - runtime_config = frigate_config.runtime_config() - assert runtime_config.cameras["back"].detect.max_disappeared == 1 - assert runtime_config.cameras["back"].detect.height == 1080 + frigate_config = FrigateConfig(**config) + assert frigate_config.cameras["back"].detect.max_disappeared == 1 + assert frigate_config.cameras["back"].detect.height == 1080 def test_default_detect(self): config = { @@ -1098,12 +1036,10 @@ class TestConfig(unittest.TestCase): } }, } - frigate_config = FrigateConfig(**config) - assert config == frigate_config.model_dump(exclude_unset=True) - runtime_config = frigate_config.runtime_config() - assert runtime_config.cameras["back"].detect.max_disappeared == 25 - assert runtime_config.cameras["back"].detect.height == 720 + frigate_config = FrigateConfig(**config) + assert frigate_config.cameras["back"].detect.max_disappeared == 25 + assert frigate_config.cameras["back"].detect.height == 720 def test_global_detect_merge(self): config = { @@ -1127,13 +1063,11 @@ class TestConfig(unittest.TestCase): } }, } - frigate_config = FrigateConfig(**config) - assert config == frigate_config.model_dump(exclude_unset=True) - runtime_config = frigate_config.runtime_config() - assert runtime_config.cameras["back"].detect.max_disappeared == 1 - assert runtime_config.cameras["back"].detect.height == 1080 - assert runtime_config.cameras["back"].detect.width == 1920 + frigate_config = FrigateConfig(**config) + assert frigate_config.cameras["back"].detect.max_disappeared == 1 + assert frigate_config.cameras["back"].detect.height == 1080 + assert frigate_config.cameras["back"].detect.width == 1920 def test_global_snapshots(self): config = { @@ -1160,12 +1094,10 @@ class TestConfig(unittest.TestCase): } }, } - frigate_config = FrigateConfig(**config) - assert config == frigate_config.model_dump(exclude_unset=True) - runtime_config = frigate_config.runtime_config() - assert runtime_config.cameras["back"].snapshots.enabled - assert runtime_config.cameras["back"].snapshots.height == 100 + frigate_config = FrigateConfig(**config) + assert frigate_config.cameras["back"].snapshots.enabled + assert frigate_config.cameras["back"].snapshots.height == 100 def test_default_snapshots(self): config = { @@ -1188,12 +1120,10 @@ class TestConfig(unittest.TestCase): } }, } - frigate_config = FrigateConfig(**config) - assert config == frigate_config.model_dump(exclude_unset=True) - runtime_config = frigate_config.runtime_config() - assert runtime_config.cameras["back"].snapshots.bounding_box - assert runtime_config.cameras["back"].snapshots.quality == 70 + frigate_config = FrigateConfig(**config) + assert frigate_config.cameras["back"].snapshots.bounding_box + assert frigate_config.cameras["back"].snapshots.quality == 70 def test_global_snapshots_merge(self): config = { @@ -1221,13 +1151,11 @@ class TestConfig(unittest.TestCase): } }, } - frigate_config = FrigateConfig(**config) - assert config == frigate_config.model_dump(exclude_unset=True) - runtime_config = frigate_config.runtime_config() - assert runtime_config.cameras["back"].snapshots.bounding_box is False - assert runtime_config.cameras["back"].snapshots.height == 150 - assert runtime_config.cameras["back"].snapshots.enabled + frigate_config = FrigateConfig(**config) + assert frigate_config.cameras["back"].snapshots.bounding_box is False + assert frigate_config.cameras["back"].snapshots.height == 150 + assert frigate_config.cameras["back"].snapshots.enabled def test_global_jsmpeg(self): config = { @@ -1251,11 +1179,9 @@ class TestConfig(unittest.TestCase): } }, } - frigate_config = FrigateConfig(**config) - assert config == frigate_config.model_dump(exclude_unset=True) - runtime_config = frigate_config.runtime_config() - assert runtime_config.cameras["back"].live.quality == 4 + frigate_config = FrigateConfig(**config) + assert frigate_config.cameras["back"].live.quality == 4 def test_default_live(self): config = { @@ -1278,11 +1204,9 @@ class TestConfig(unittest.TestCase): } }, } - frigate_config = FrigateConfig(**config) - assert config == frigate_config.model_dump(exclude_unset=True) - runtime_config = frigate_config.runtime_config() - assert runtime_config.cameras["back"].live.quality == 8 + frigate_config = FrigateConfig(**config) + assert frigate_config.cameras["back"].live.quality == 8 def test_global_live_merge(self): config = { @@ -1309,12 +1233,10 @@ class TestConfig(unittest.TestCase): } }, } - frigate_config = FrigateConfig(**config) - assert config == frigate_config.model_dump(exclude_unset=True) - runtime_config = frigate_config.runtime_config() - assert runtime_config.cameras["back"].live.quality == 7 - assert runtime_config.cameras["back"].live.height == 480 + frigate_config = FrigateConfig(**config) + assert frigate_config.cameras["back"].live.quality == 7 + assert frigate_config.cameras["back"].live.height == 480 def test_global_timestamp_style(self): config = { @@ -1338,11 +1260,9 @@ class TestConfig(unittest.TestCase): } }, } - frigate_config = FrigateConfig(**config) - assert config == frigate_config.model_dump(exclude_unset=True) - runtime_config = frigate_config.runtime_config() - assert runtime_config.cameras["back"].timestamp_style.position == "bl" + frigate_config = FrigateConfig(**config) + assert frigate_config.cameras["back"].timestamp_style.position == "bl" def test_default_timestamp_style(self): config = { @@ -1365,11 +1285,9 @@ class TestConfig(unittest.TestCase): } }, } - frigate_config = FrigateConfig(**config) - assert config == frigate_config.model_dump(exclude_unset=True) - runtime_config = frigate_config.runtime_config() - assert runtime_config.cameras["back"].timestamp_style.position == "tl" + frigate_config = FrigateConfig(**config) + assert frigate_config.cameras["back"].timestamp_style.position == "tl" def test_global_timestamp_style_merge(self): config = { @@ -1394,12 +1312,10 @@ class TestConfig(unittest.TestCase): } }, } - frigate_config = FrigateConfig(**config) - assert config == frigate_config.model_dump(exclude_unset=True) - runtime_config = frigate_config.runtime_config() - assert runtime_config.cameras["back"].timestamp_style.position == "bl" - assert runtime_config.cameras["back"].timestamp_style.thickness == 4 + frigate_config = FrigateConfig(**config) + assert frigate_config.cameras["back"].timestamp_style.position == "bl" + assert frigate_config.cameras["back"].timestamp_style.thickness == 4 def test_allow_retain_to_be_a_decimal(self): config = { @@ -1423,11 +1339,9 @@ class TestConfig(unittest.TestCase): } }, } - frigate_config = FrigateConfig(**config) - assert config == frigate_config.model_dump(exclude_unset=True) - runtime_config = frigate_config.runtime_config() - assert runtime_config.cameras["back"].snapshots.retain.default == 1.5 + frigate_config = FrigateConfig(**config) + assert frigate_config.cameras["back"].snapshots.retain.default == 1.5 def test_fails_on_bad_camera_name(self): config = { @@ -1452,11 +1366,7 @@ class TestConfig(unittest.TestCase): }, } - frigate_config = FrigateConfig(**config) - - self.assertRaises( - ValidationError, lambda: frigate_config.runtime_config().cameras - ) + self.assertRaises(ValidationError, lambda: FrigateConfig(**config).cameras) def test_fails_on_bad_segment_time(self): config = { @@ -1484,11 +1394,9 @@ class TestConfig(unittest.TestCase): }, } - frigate_config = FrigateConfig(**config) - self.assertRaises( ValueError, - lambda: frigate_config.runtime_config().ffmpeg.output_args.record, + lambda: FrigateConfig(**config).ffmpeg.output_args.record, ) def test_fails_zone_defines_untracked_object(self): @@ -1520,9 +1428,7 @@ class TestConfig(unittest.TestCase): }, } - frigate_config = FrigateConfig(**config) - - self.assertRaises(ValueError, lambda: frigate_config.runtime_config().cameras) + self.assertRaises(ValueError, lambda: FrigateConfig(**config).cameras) def test_fails_duplicate_keys(self): raw_config = """ @@ -1563,13 +1469,11 @@ class TestConfig(unittest.TestCase): } }, } - frigate_config = FrigateConfig(**config) - assert config == frigate_config.model_dump(exclude_unset=True) - runtime_config = frigate_config.runtime_config() - assert "dog" in runtime_config.cameras["back"].objects.filters - assert runtime_config.cameras["back"].objects.filters["dog"].min_ratio == 0.2 - assert runtime_config.cameras["back"].objects.filters["dog"].max_ratio == 10.1 + frigate_config = FrigateConfig(**config) + assert "dog" in frigate_config.cameras["back"].objects.filters + assert frigate_config.cameras["back"].objects.filters["dog"].min_ratio == 0.2 + assert frigate_config.cameras["back"].objects.filters["dog"].max_ratio == 10.1 def test_valid_movement_weights(self): config = { @@ -1592,10 +1496,9 @@ class TestConfig(unittest.TestCase): } }, } - frigate_config = FrigateConfig(**config) - runtime_config = frigate_config.runtime_config() - assert runtime_config.cameras["back"].onvif.autotracking.movement_weights == [ + frigate_config = FrigateConfig(**config) + assert frigate_config.cameras["back"].onvif.autotracking.movement_weights == [ "0.0", "1.0", "1.23", diff --git a/frigate/test/test_ffmpeg_presets.py b/frigate/test/test_ffmpeg_presets.py index 0275469cd..7916b471c 100644 --- a/frigate/test/test_ffmpeg_presets.py +++ b/frigate/test/test_ffmpeg_presets.py @@ -36,16 +36,13 @@ class TestFfmpegPresets(unittest.TestCase): } def test_default_ffmpeg(self): - frigate_config = FrigateConfig(**self.default_ffmpeg) - frigate_config.cameras["back"].create_ffmpeg_cmds() - assert self.default_ffmpeg == frigate_config.dict(exclude_unset=True) + FrigateConfig(**self.default_ffmpeg) def test_ffmpeg_hwaccel_preset(self): self.default_ffmpeg["cameras"]["back"]["ffmpeg"]["hwaccel_args"] = ( "preset-rpi-64-h264" ) frigate_config = FrigateConfig(**self.default_ffmpeg) - frigate_config.cameras["back"].create_ffmpeg_cmds() assert "preset-rpi-64-h264" not in ( " ".join(frigate_config.cameras["back"].ffmpeg_cmds[0]["cmd"]) ) @@ -58,7 +55,6 @@ class TestFfmpegPresets(unittest.TestCase): "-other-hwaccel args" ) frigate_config = FrigateConfig(**self.default_ffmpeg) - frigate_config.cameras["back"].create_ffmpeg_cmds() assert "-other-hwaccel args" in ( " ".join(frigate_config.cameras["back"].ffmpeg_cmds[0]["cmd"]) ) @@ -73,7 +69,6 @@ class TestFfmpegPresets(unittest.TestCase): "fps": 10, } frigate_config = FrigateConfig(**self.default_ffmpeg) - frigate_config.cameras["back"].create_ffmpeg_cmds() assert "preset-nvidia-h264" not in ( " ".join(frigate_config.cameras["back"].ffmpeg_cmds[0]["cmd"]) ) @@ -89,8 +84,6 @@ class TestFfmpegPresets(unittest.TestCase): "preset-rtsp-generic" ) frigate_preset_config = FrigateConfig(**self.default_ffmpeg) - frigate_config.cameras["back"].create_ffmpeg_cmds() - frigate_preset_config.cameras["back"].create_ffmpeg_cmds() assert ( # Ignore global and user_agent args in comparison frigate_preset_config.cameras["back"].ffmpeg_cmds[0]["cmd"] @@ -102,7 +95,6 @@ class TestFfmpegPresets(unittest.TestCase): "preset-rtmp-generic" ) frigate_config = FrigateConfig(**self.default_ffmpeg) - frigate_config.cameras["back"].create_ffmpeg_cmds() assert "preset-rtmp-generic" not in ( " ".join(frigate_config.cameras["back"].ffmpeg_cmds[0]["cmd"]) ) @@ -117,7 +109,6 @@ class TestFfmpegPresets(unittest.TestCase): argsList = defaultArgsList + ["-some", "arg with space"] self.default_ffmpeg["cameras"]["back"]["ffmpeg"]["input_args"] = argsString frigate_config = FrigateConfig(**self.default_ffmpeg) - frigate_config.cameras["back"].create_ffmpeg_cmds() assert set(argsList).issubset( frigate_config.cameras["back"].ffmpeg_cmds[0]["cmd"] ) @@ -125,7 +116,6 @@ class TestFfmpegPresets(unittest.TestCase): def test_ffmpeg_input_not_preset(self): self.default_ffmpeg["cameras"]["back"]["ffmpeg"]["input_args"] = "-some inputs" frigate_config = FrigateConfig(**self.default_ffmpeg) - frigate_config.cameras["back"].create_ffmpeg_cmds() assert "-some inputs" in ( " ".join(frigate_config.cameras["back"].ffmpeg_cmds[0]["cmd"]) ) @@ -135,7 +125,6 @@ class TestFfmpegPresets(unittest.TestCase): "preset-record-generic-audio-aac" ) frigate_config = FrigateConfig(**self.default_ffmpeg) - frigate_config.cameras["back"].create_ffmpeg_cmds() assert "preset-record-generic-audio-aac" not in ( " ".join(frigate_config.cameras["back"].ffmpeg_cmds[0]["cmd"]) ) @@ -148,7 +137,6 @@ class TestFfmpegPresets(unittest.TestCase): "-some output" ) frigate_config = FrigateConfig(**self.default_ffmpeg) - frigate_config.cameras["back"].create_ffmpeg_cmds() assert "-some output" in ( " ".join(frigate_config.cameras["back"].ffmpeg_cmds[0]["cmd"]) ) diff --git a/frigate/test/test_http.py b/frigate/test/test_http.py index 936dc80e5..127a82b72 100644 --- a/frigate/test/test_http.py +++ b/frigate/test/test_http.py @@ -345,7 +345,7 @@ class TestHttp(unittest.TestCase): def test_config(self): app = create_app( - FrigateConfig(**self.minimal_config).runtime_config(), + FrigateConfig(**self.minimal_config), self.db, None, None, @@ -363,7 +363,7 @@ class TestHttp(unittest.TestCase): def test_recordings(self): app = create_app( - FrigateConfig(**self.minimal_config).runtime_config(), + FrigateConfig(**self.minimal_config), self.db, None, None, @@ -385,7 +385,7 @@ class TestHttp(unittest.TestCase): stats = Mock(spec=StatsEmitter) stats.get_latest_stats.return_value = self.test_stats app = create_app( - FrigateConfig(**self.minimal_config).runtime_config(), + FrigateConfig(**self.minimal_config), self.db, None, None, diff --git a/process_clip.py b/process_clip.py index 77cfdba2c..54bbf0c1e 100644 --- a/process_clip.py +++ b/process_clip.py @@ -280,10 +280,7 @@ def process(path, label, output, debug_path): json_config["cameras"]["camera"]["ffmpeg"]["inputs"][0]["path"] = c frigate_config = FrigateConfig(**json_config) - runtime_config = frigate_config.runtime_config() - runtime_config.cameras["camera"].create_ffmpeg_cmds() - - process_clip = ProcessClip(c, frame_shape, runtime_config) + process_clip = ProcessClip(c, frame_shape, frigate_config) process_clip.load_frames() process_clip.process_frames(object_detector, objects_to_track=[label])