diff --git a/docker/main/rootfs/etc/s6-overlay/s6-rc.d/chroma/run b/docker/main/rootfs/etc/s6-overlay/s6-rc.d/chroma/run index 45b44779b..ef477d8a2 100644 --- a/docker/main/rootfs/etc/s6-overlay/s6-rc.d/chroma/run +++ b/docker/main/rootfs/etc/s6-overlay/s6-rc.d/chroma/run @@ -9,8 +9,19 @@ set -o errexit -o nounset -o pipefail # Tell S6-Overlay not to restart this service s6-svc -O . -echo "[INFO] Starting ChromaDB..." +search_enabled=`python3 /usr/local/semantic_search/get_search_settings.py | jq -r .enabled` # Replace the bash process with the Frigate process, redirecting stderr to stdout exec 2>&1 -exec /usr/local/chroma run --path /config/chroma --host 127.0.0.1 + +if [[ "$search_enabled" == 'true' ]]; then + echo "[INFO] Starting ChromaDB..." + exec /usr/local/chroma run --path /config/chroma --host 127.0.0.1 +else + while true + do + sleep 9999 + continue + done + exit 0 +fi diff --git a/docker/main/rootfs/usr/local/semantic_search/get_search_settings.py b/docker/main/rootfs/usr/local/semantic_search/get_search_settings.py new file mode 100644 index 000000000..e4ec4ea1c --- /dev/null +++ b/docker/main/rootfs/usr/local/semantic_search/get_search_settings.py @@ -0,0 +1,28 @@ +"""Prints the semantic_search config as json to stdout.""" + +import json +import os + +import yaml + +config_file = os.environ.get("CONFIG_FILE", "/config/config.yml") + +# Check if we can use .yaml instead of .yml +config_file_yaml = config_file.replace(".yml", ".yaml") +if os.path.isfile(config_file_yaml): + config_file = config_file_yaml + +try: + with open(config_file) as f: + raw_config = f.read() + + if config_file.endswith((".yaml", ".yml")): + config: dict[str, any] = yaml.safe_load(raw_config) + elif config_file.endswith(".json"): + config: dict[str, any] = json.loads(raw_config) +except FileNotFoundError: + config: dict[str, any] = {} + +search_config: dict[str, any] = config.get("semantic_search", {"enabled": False}) + +print(json.dumps(search_config)) diff --git a/frigate/api/app.py b/frigate/api/app.py index 79a78f454..732cdcf76 100644 --- a/frigate/api/app.py +++ b/frigate/api/app.py @@ -7,6 +7,7 @@ import os import traceback from datetime import datetime, timedelta from functools import reduce +from typing import Optional import requests from flask import Blueprint, Flask, current_app, jsonify, make_response, request @@ -55,7 +56,7 @@ bp.register_blueprint(NotificationBp) def create_app( frigate_config, database: SqliteQueueDatabase, - embeddings: EmbeddingsContext, + embeddings: Optional[EmbeddingsContext], detected_frames_processor, storage_maintainer: StorageMaintainer, onvif: OnvifController, diff --git a/frigate/app.py b/frigate/app.py index dcc61a58c..9149f9854 100644 --- a/frigate/app.py +++ b/frigate/app.py @@ -321,6 +321,10 @@ class FrigateApp: logger.info(f"Review process started: {review_segment_process.pid}") def init_embeddings_manager(self) -> None: + if not self.config.semantic_search.enabled: + self.embeddings = None + return + # Create a client for other processes to use self.embeddings = EmbeddingsContext() embedding_process = mp.Process( @@ -816,7 +820,8 @@ class FrigateApp: self.db.stop() # Save embeddings stats to disk - self.embeddings.save_stats() + if self.embeddings: + self.embeddings.save_stats() # Stop Communicators self.inter_process_communicator.stop() diff --git a/frigate/config.py b/frigate/config.py index 126d964ff..a430b3d6c 100644 --- a/frigate/config.py +++ b/frigate/config.py @@ -736,7 +736,7 @@ class ReviewConfig(FrigateBaseModel): class SemanticSearchConfig(FrigateBaseModel): - enabled: bool = Field(default=True, title="Enable semantic search.") + enabled: bool = Field(default=False, title="Enable semantic search.") reindex: Optional[bool] = Field( default=False, title="Reindex all detections on startup." )