mirror of
https://github.com/blakeblackshear/frigate.git
synced 2026-08-10 12:51:11 +03:00
Increase ruff coverage (#23644)
CI / AMD64 Build (push) Waiting to run
CI / ARM Build (push) Waiting to run
CI / AMD64 Extra Build (push) Blocked by required conditions
CI / ARM Extra Build (push) Blocked by required conditions
CI / Synaptics Build (push) Blocked by required conditions
CI / Assemble and push default build (push) Blocked by required conditions
CI / Jetson Jetpack 6 (push) Waiting to run
CI / AMD64 Build (push) Waiting to run
CI / ARM Build (push) Waiting to run
CI / AMD64 Extra Build (push) Blocked by required conditions
CI / ARM Extra Build (push) Blocked by required conditions
CI / Synaptics Build (push) Blocked by required conditions
CI / Assemble and push default build (push) Blocked by required conditions
CI / Jetson Jetpack 6 (push) Waiting to run
* Pin ruff * Add python upgrade fixes This enables python upgrade checks in ruff to look for deprecated types and patterns. This namely fixes: - usage of deprecated `Typing` which is now built in - some specific exceptions which are caught and have new aliases Some specific UP checks were also ignored as they are stylistic / unimportant and likely to cause bugs * Remove async blocking calls Use asyncio.to_thread on two remaining blocking calls to fix hanging event thread loop. Enable this specific rule to block it in the future. * Use proper logging mechanism * Correctly format logs * Raise with context When raising an exception include the from context to improve debugging * Cleanup
This commit is contained in:
@@ -1,6 +1,5 @@
|
||||
import logging
|
||||
from abc import ABC, abstractmethod
|
||||
from typing import List
|
||||
|
||||
import numpy as np
|
||||
|
||||
@@ -11,7 +10,7 @@ logger = logging.getLogger(__name__)
|
||||
|
||||
class DetectionApi(ABC):
|
||||
type_key: str
|
||||
supported_models: List[ModelTypeEnum]
|
||||
supported_models: list[ModelTypeEnum]
|
||||
|
||||
@abstractmethod
|
||||
def __init__(self, detector_config: BaseDetectorConfig):
|
||||
|
||||
@@ -491,7 +491,7 @@ class RKNNModelRunner(BaseModelRunner):
|
||||
|
||||
except ImportError:
|
||||
logger.error("RKNN Lite not available")
|
||||
raise ImportError("RKNN Lite not available")
|
||||
raise ImportError("RKNN Lite not available") from None
|
||||
except Exception as e:
|
||||
logger.error(f"Error loading RKNN model: {e}")
|
||||
raise
|
||||
|
||||
@@ -3,7 +3,7 @@ import json
|
||||
import logging
|
||||
import os
|
||||
from enum import Enum
|
||||
from typing import Any, Dict, Optional, Tuple
|
||||
from typing import Any
|
||||
|
||||
import requests
|
||||
from pydantic import BaseModel, ConfigDict, Field
|
||||
@@ -45,12 +45,12 @@ class ModelTypeEnum(str, Enum):
|
||||
|
||||
|
||||
class ModelConfig(BaseModel):
|
||||
path: Optional[str] = Field(
|
||||
path: str | None = Field(
|
||||
None,
|
||||
title="Custom object detector model path",
|
||||
description="Path to a custom detection model file (or plus://<model_id> for Frigate+ models).",
|
||||
)
|
||||
labelmap_path: Optional[str] = Field(
|
||||
labelmap_path: str | None = Field(
|
||||
None,
|
||||
title="Label map for custom object detector",
|
||||
description="Path to a labelmap file that maps numeric classes to string labels for the detector.",
|
||||
@@ -65,12 +65,12 @@ class ModelConfig(BaseModel):
|
||||
title="Object detection model input height",
|
||||
description="Height of the model input tensor in pixels.",
|
||||
)
|
||||
labelmap: Dict[int, str] = Field(
|
||||
labelmap: dict[int, str] = Field(
|
||||
default_factory=dict,
|
||||
title="Labelmap customization",
|
||||
description="Overrides or remapping entries to merge into the standard labelmap.",
|
||||
)
|
||||
attributes_map: Dict[str, list[str]] = Field(
|
||||
attributes_map: dict[str, list[str]] = Field(
|
||||
default=DEFAULT_ATTRIBUTE_LABEL_MAP,
|
||||
title="Map of object labels to their attribute labels",
|
||||
description="Mapping from object labels to attribute labels used to attach metadata (for example 'car' -> ['license_plate']).",
|
||||
@@ -95,18 +95,18 @@ class ModelConfig(BaseModel):
|
||||
title="Object Detection Model Type",
|
||||
description="Detector model architecture type (ssd, yolox, yolonas) used by some detectors for optimization.",
|
||||
)
|
||||
_merged_labelmap: Optional[Dict[int, str]] = PrivateAttr()
|
||||
_colormap: Dict[int, Tuple[int, int, int]] = PrivateAttr()
|
||||
_merged_labelmap: dict[int, str] | None = PrivateAttr()
|
||||
_colormap: dict[int, tuple[int, int, int]] = PrivateAttr()
|
||||
_all_attributes: list[str] = PrivateAttr()
|
||||
_all_attribute_logos: list[str] = PrivateAttr()
|
||||
_model_hash: str = PrivateAttr()
|
||||
|
||||
@property
|
||||
def merged_labelmap(self) -> Dict[int, str]:
|
||||
def merged_labelmap(self) -> dict[int, str]:
|
||||
return self._merged_labelmap
|
||||
|
||||
@property
|
||||
def colormap(self) -> Dict[int, Tuple[int, int, int]]:
|
||||
def colormap(self) -> dict[int, tuple[int, int, int]]:
|
||||
return self._colormap
|
||||
|
||||
@property
|
||||
@@ -171,7 +171,7 @@ class ModelConfig(BaseModel):
|
||||
with open(model_info_path, "w") as f:
|
||||
json.dump(model_info, f)
|
||||
else:
|
||||
with open(model_info_path, "r") as f:
|
||||
with open(model_info_path) as f:
|
||||
model_info: dict[str, Any] = json.load(f)
|
||||
|
||||
if detector and detector not in model_info["supportedDetectors"]:
|
||||
@@ -240,12 +240,12 @@ class BaseDetectorConfig(BaseModel):
|
||||
title="Detector Type",
|
||||
description="Type of detector to use for object detection (for example 'cpu', 'edgetpu', 'openvino').",
|
||||
)
|
||||
model: Optional[ModelConfig] = Field(
|
||||
model: ModelConfig | None = Field(
|
||||
default=None,
|
||||
title="Detector specific model configuration",
|
||||
description="Detector-specific model configuration options (path, input size, etc.).",
|
||||
)
|
||||
model_path: Optional[str] = Field(
|
||||
model_path: str | None = Field(
|
||||
default=None,
|
||||
title="Detector specific model path",
|
||||
description="File path to the detector model binary if required by the chosen detector.",
|
||||
|
||||
@@ -2,10 +2,9 @@ import importlib
|
||||
import logging
|
||||
import pkgutil
|
||||
from enum import Enum
|
||||
from typing import Union
|
||||
from typing import Annotated, Union
|
||||
|
||||
from pydantic import Field
|
||||
from typing_extensions import Annotated
|
||||
|
||||
from . import plugins
|
||||
from .detection_api import DetectionApi
|
||||
@@ -37,6 +36,6 @@ class StrEnum(str, Enum):
|
||||
DetectorTypeEnum = StrEnum("DetectorTypeEnum", {k: k for k in api_types})
|
||||
|
||||
DetectorConfig = Annotated[
|
||||
Union[tuple(BaseDetectorConfig.__subclasses__())],
|
||||
Union[tuple(BaseDetectorConfig.__subclasses__())], # noqa: UP007
|
||||
Field(discriminator="type"),
|
||||
]
|
||||
|
||||
@@ -39,8 +39,7 @@ class Axengine(DetectionApi):
|
||||
try:
|
||||
import axengine as axe
|
||||
except ModuleNotFoundError:
|
||||
raise ImportError("AXEngine is not installed.")
|
||||
return
|
||||
raise ImportError("AXEngine is not installed.") from None
|
||||
|
||||
logger.info("__init__ axengine")
|
||||
super().__init__(config)
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import logging
|
||||
from typing import Literal
|
||||
|
||||
from pydantic import ConfigDict, Field
|
||||
from typing_extensions import Literal
|
||||
|
||||
from frigate.detectors.detection_api import DetectionApi
|
||||
from frigate.detectors.detector_config import BaseDetectorConfig
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
import io
|
||||
import logging
|
||||
from typing import Literal
|
||||
|
||||
import numpy as np
|
||||
import requests
|
||||
from PIL import Image
|
||||
from pydantic import ConfigDict, Field
|
||||
from typing_extensions import Literal
|
||||
|
||||
from frigate.detectors.detection_api import DetectionApi
|
||||
from frigate.detectors.detector_config import BaseDetectorConfig
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
import logging
|
||||
import queue
|
||||
from typing import Literal
|
||||
|
||||
import numpy as np
|
||||
from pydantic import ConfigDict, Field
|
||||
from typing_extensions import Literal
|
||||
|
||||
from frigate.detectors.detection_api import DetectionApi
|
||||
from frigate.detectors.detector_config import BaseDetectorConfig
|
||||
@@ -46,7 +46,7 @@ class DGDetector(DetectionApi):
|
||||
try:
|
||||
import degirum as dg
|
||||
except ModuleNotFoundError:
|
||||
raise ImportError("Unable to import DeGirum detector.")
|
||||
raise ImportError("Unable to import DeGirum detector.") from None
|
||||
|
||||
self._queue = queue.Queue()
|
||||
self._zoo = dg.connect(
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
import logging
|
||||
import math
|
||||
import os
|
||||
from typing import Literal
|
||||
|
||||
import cv2
|
||||
import numpy as np
|
||||
from pydantic import ConfigDict, Field
|
||||
from typing_extensions import Literal
|
||||
|
||||
from frigate.detectors.detection_api import DetectionApi
|
||||
from frigate.detectors.detector_config import BaseDetectorConfig, ModelTypeEnum
|
||||
|
||||
@@ -4,12 +4,11 @@ import subprocess
|
||||
import threading
|
||||
import urllib.request
|
||||
from functools import partial
|
||||
from typing import Dict, List, Optional, Tuple
|
||||
from typing import Literal
|
||||
|
||||
import cv2
|
||||
import numpy as np
|
||||
from pydantic import ConfigDict, Field
|
||||
from typing_extensions import Literal
|
||||
|
||||
from frigate.const import MODEL_CACHE_DIR
|
||||
from frigate.detectors.detection_api import DetectionApi
|
||||
@@ -83,8 +82,8 @@ class HailoAsyncInference:
|
||||
input_store: RequestStore,
|
||||
output_store: ResponseStore,
|
||||
batch_size: int = 1,
|
||||
input_type: Optional[str] = None,
|
||||
output_type: Optional[Dict[str, str]] = None,
|
||||
input_type: str | None = None,
|
||||
output_type: dict[str, str] | None = None,
|
||||
send_original_frame: bool = False,
|
||||
) -> None:
|
||||
# when importing hailo it activates the driver
|
||||
@@ -125,9 +124,9 @@ class HailoAsyncInference:
|
||||
def callback(
|
||||
self,
|
||||
completion_info,
|
||||
bindings_list: List,
|
||||
input_batch: List,
|
||||
request_ids: List[int],
|
||||
bindings_list: list,
|
||||
input_batch: list,
|
||||
request_ids: list[int],
|
||||
):
|
||||
if completion_info.exception:
|
||||
logger.error(f"Inference error: {completion_info.exception}")
|
||||
@@ -163,7 +162,7 @@ class HailoAsyncInference:
|
||||
}
|
||||
return configured_infer_model.create_bindings(output_buffers=output_buffers)
|
||||
|
||||
def get_input_shape(self) -> Tuple[int, ...]:
|
||||
def get_input_shape(self) -> tuple[int, ...]:
|
||||
return self.hef.get_input_vstream_infos()[0].shape
|
||||
|
||||
def run(self) -> None:
|
||||
@@ -304,7 +303,7 @@ class HailoDetector(DetectionApi):
|
||||
urllib.request.urlretrieve(url, destination)
|
||||
logger.debug(f"Downloaded model to {destination}")
|
||||
except Exception as e:
|
||||
raise RuntimeError(f"Failed to download model from {url}: {str(e)}")
|
||||
raise RuntimeError(f"Failed to download model from {url}: {str(e)}") from e
|
||||
|
||||
def check_and_prepare(self) -> str:
|
||||
if not os.path.exists(self.cache_dir):
|
||||
@@ -350,7 +349,7 @@ class HailoDetector(DetectionApi):
|
||||
if not self.inference_thread.is_alive():
|
||||
raise RuntimeError(
|
||||
"HailoRT inference thread has stopped, restart required."
|
||||
)
|
||||
) from None
|
||||
|
||||
return np.zeros((20, 6), dtype=np.float32)
|
||||
|
||||
|
||||
@@ -5,11 +5,11 @@ import shutil
|
||||
import urllib.request
|
||||
import zipfile
|
||||
from queue import Queue
|
||||
from typing import Literal
|
||||
|
||||
import cv2
|
||||
import numpy as np
|
||||
from pydantic import BaseModel, ConfigDict, Field
|
||||
from typing_extensions import Literal
|
||||
|
||||
from frigate.detectors.detection_api import DetectionApi
|
||||
from frigate.detectors.detector_config import (
|
||||
@@ -61,7 +61,7 @@ class MemryXDetector(DetectionApi):
|
||||
except ModuleNotFoundError:
|
||||
raise ImportError(
|
||||
"MemryX SDK is not installed. Install it and set up MIX environment."
|
||||
)
|
||||
) from None
|
||||
return
|
||||
|
||||
# Initialize stop_event as None, will be set later by set_stop_event()
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import logging
|
||||
from typing import Literal
|
||||
|
||||
import numpy as np
|
||||
from pydantic import ConfigDict, Field
|
||||
from typing_extensions import Literal
|
||||
|
||||
from frigate.detectors.detection_api import DetectionApi
|
||||
from frigate.detectors.detection_runners import get_optimized_runner
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
import logging
|
||||
from typing import Literal
|
||||
|
||||
import numpy as np
|
||||
import openvino as ov
|
||||
from pydantic import ConfigDict, Field
|
||||
from typing_extensions import Literal
|
||||
|
||||
from frigate.detectors.detection_api import DetectionApi
|
||||
from frigate.detectors.detection_runners import OpenVINOModelRunner
|
||||
|
||||
@@ -90,7 +90,7 @@ class Rknn(DetectionApi):
|
||||
with open("/proc/device-tree/compatible") as file:
|
||||
soc = file.read().split(",")[-1].strip("\x00")
|
||||
except FileNotFoundError:
|
||||
raise Exception("Make sure to run docker in privileged mode.")
|
||||
raise Exception("Make sure to run docker in privileged mode.") from None
|
||||
|
||||
if soc not in SUPPORTED_RK_SOCS:
|
||||
raise Exception(
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
import logging
|
||||
import os
|
||||
from typing import Literal
|
||||
|
||||
import numpy as np
|
||||
from pydantic import ConfigDict
|
||||
from typing_extensions import Literal
|
||||
|
||||
from frigate.detectors.detection_api import DetectionApi
|
||||
from frigate.detectors.detector_config import (
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import logging
|
||||
from typing import Literal
|
||||
|
||||
from pydantic import ConfigDict
|
||||
from typing_extensions import Literal
|
||||
|
||||
from frigate.detectors.detection_api import DetectionApi
|
||||
from frigate.detectors.detector_config import BaseDetectorConfig
|
||||
|
||||
@@ -14,8 +14,9 @@ try:
|
||||
except ModuleNotFoundError:
|
||||
TRT_SUPPORT = False
|
||||
|
||||
from typing import Literal
|
||||
|
||||
from pydantic import ConfigDict, Field
|
||||
from typing_extensions import Literal
|
||||
|
||||
from frigate.detectors.detection_api import DetectionApi
|
||||
from frigate.detectors.detector_config import BaseDetectorConfig
|
||||
@@ -58,7 +59,7 @@ class TensorRTDetectorConfig(BaseDetectorConfig):
|
||||
)
|
||||
|
||||
|
||||
class HostDeviceMem(object):
|
||||
class HostDeviceMem:
|
||||
"""Simple helper data class that's a little nicer to use than a 2-tuple."""
|
||||
|
||||
def __init__(self, host_mem, device_mem, nbytes, size):
|
||||
|
||||
@@ -1,12 +1,11 @@
|
||||
import json
|
||||
import logging
|
||||
import os
|
||||
from typing import Any, List
|
||||
from typing import Any, Literal
|
||||
|
||||
import numpy as np
|
||||
import zmq
|
||||
from pydantic import ConfigDict, Field
|
||||
from typing_extensions import Literal
|
||||
|
||||
from frigate.detectors.detection_api import DetectionApi
|
||||
from frigate.detectors.detector_config import BaseDetectorConfig
|
||||
@@ -274,7 +273,7 @@ class ZmqIpcDetector(DetectionApi):
|
||||
}
|
||||
return json.dumps(header).encode("utf-8")
|
||||
|
||||
def _decode_response(self, frames: List[bytes]) -> np.ndarray:
|
||||
def _decode_response(self, frames: list[bytes]) -> np.ndarray:
|
||||
try:
|
||||
if len(frames) == 1:
|
||||
# Single-frame raw float32 (20x6)
|
||||
|
||||
Reference in New Issue
Block a user