mirror of
https://github.com/khoj-ai/khoj.git
synced 2025-02-17 16:14:21 +00:00
Use single func to configure server via API and on server start
Improve error messages on failure to configure server components
This commit is contained in:
parent
ba47f2ab39
commit
58d86d7876
3 changed files with 67 additions and 55 deletions
|
@ -37,23 +37,40 @@ from khoj.search_filter.file_filter import FileFilter
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
def configure_server(args, required=False):
|
def initialize_server(
|
||||||
if args.config is None:
|
config: Optional[FullConfig], regenerate: bool, type: Optional[SearchType] = None, required=False
|
||||||
if required:
|
):
|
||||||
logger.error(
|
if config is None and required:
|
||||||
f"Exiting as Khoj is not configured.\nConfigure it via http://localhost:42110/config or by editing {state.config_file}."
|
logger.error(
|
||||||
)
|
f"🚨 Exiting as Khoj is not configured.\nConfigure it via http://localhost:42110/config or by editing {state.config_file}."
|
||||||
sys.exit(1)
|
)
|
||||||
else:
|
sys.exit(1)
|
||||||
logger.warning(
|
elif config is None:
|
||||||
f"Khoj is not configured.\nConfigure it via http://localhost:42110/config, plugins or by editing {state.config_file}."
|
logger.warning(
|
||||||
)
|
f"🚨 Khoj is not configured.\nConfigure it via http://localhost:42110/config, plugins or by editing {state.config_file}."
|
||||||
return
|
)
|
||||||
else:
|
return None
|
||||||
state.config = args.config
|
|
||||||
|
try:
|
||||||
|
configure_server(config, regenerate, type)
|
||||||
|
except Exception as e:
|
||||||
|
logger.error(f"🚨 Failed to configure server on app load: {e}")
|
||||||
|
raise e
|
||||||
|
|
||||||
|
|
||||||
|
def configure_server(config: FullConfig, regenerate: bool, search_type: Optional[SearchType] = None):
|
||||||
|
# Update Config
|
||||||
|
state.config = config
|
||||||
|
|
||||||
# Initialize Processor from Config
|
# Initialize Processor from Config
|
||||||
state.processor_config = configure_processor(args.config.processor)
|
try:
|
||||||
|
state.search_index_lock.acquire()
|
||||||
|
state.processor_config = configure_processor(state.config.processor)
|
||||||
|
except Exception as e:
|
||||||
|
logger.error(f"🚨 Failed to configure processor")
|
||||||
|
raise e
|
||||||
|
finally:
|
||||||
|
state.search_index_lock.release()
|
||||||
|
|
||||||
# Initialize Search Models from Config
|
# Initialize Search Models from Config
|
||||||
try:
|
try:
|
||||||
|
@ -61,7 +78,8 @@ def configure_server(args, required=False):
|
||||||
state.SearchType = configure_search_types(state.config)
|
state.SearchType = configure_search_types(state.config)
|
||||||
state.search_models = configure_search(state.search_models, state.config.search_type)
|
state.search_models = configure_search(state.search_models, state.config.search_type)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.error(f"🚨 Error configuring search models on app load: {e}")
|
logger.error(f"🚨 Failed to configure search models")
|
||||||
|
raise e
|
||||||
finally:
|
finally:
|
||||||
state.search_index_lock.release()
|
state.search_index_lock.release()
|
||||||
|
|
||||||
|
@ -70,10 +88,11 @@ def configure_server(args, required=False):
|
||||||
try:
|
try:
|
||||||
state.search_index_lock.acquire()
|
state.search_index_lock.acquire()
|
||||||
state.content_index = configure_content(
|
state.content_index = configure_content(
|
||||||
state.content_index, state.config.content_type, state.search_models, args.regenerate
|
state.content_index, state.config.content_type, state.search_models, regenerate, search_type
|
||||||
)
|
)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.error(f"🚨 Error configuring content index on app load: {e}")
|
logger.error(f"🚨 Failed to index content")
|
||||||
|
raise e
|
||||||
finally:
|
finally:
|
||||||
state.search_index_lock.release()
|
state.search_index_lock.release()
|
||||||
|
|
||||||
|
@ -118,10 +137,10 @@ def configure_search_types(config: FullConfig):
|
||||||
return Enum("SearchType", merge_dicts(core_search_types, plugin_search_types))
|
return Enum("SearchType", merge_dicts(core_search_types, plugin_search_types))
|
||||||
|
|
||||||
|
|
||||||
def configure_search(search_models: SearchModels, search_config: SearchConfig) -> Optional[SearchModels]:
|
def configure_search(search_models: SearchModels, search_config: Optional[SearchConfig]) -> Optional[SearchModels]:
|
||||||
# Run Validation Checks
|
# Run Validation Checks
|
||||||
if search_config is None:
|
if search_config is None:
|
||||||
logger.warning("🚨 No Search type is configured.")
|
logger.warning("🚨 No Search configuration available.")
|
||||||
return None
|
return None
|
||||||
if search_models is None:
|
if search_models is None:
|
||||||
search_models = SearchModels()
|
search_models = SearchModels()
|
||||||
|
@ -147,7 +166,7 @@ def configure_content(
|
||||||
) -> Optional[ContentIndex]:
|
) -> Optional[ContentIndex]:
|
||||||
# Run Validation Checks
|
# Run Validation Checks
|
||||||
if content_config is None:
|
if content_config is None:
|
||||||
logger.warning("🚨 No Content type is configured.")
|
logger.warning("🚨 No Content configuration available.")
|
||||||
return None
|
return None
|
||||||
if content_index is None:
|
if content_index is None:
|
||||||
content_index = ContentIndex()
|
content_index = ContentIndex()
|
||||||
|
@ -242,9 +261,10 @@ def configure_content(
|
||||||
return content_index
|
return content_index
|
||||||
|
|
||||||
|
|
||||||
def configure_processor(processor_config: ProcessorConfig):
|
def configure_processor(processor_config: Optional[ProcessorConfig]):
|
||||||
if not processor_config:
|
if not processor_config:
|
||||||
return
|
logger.warning("🚨 No Processor configuration available.")
|
||||||
|
return None
|
||||||
|
|
||||||
processor = ProcessorConfigModel()
|
processor = ProcessorConfigModel()
|
||||||
|
|
||||||
|
|
|
@ -27,7 +27,7 @@ from rich.logging import RichHandler
|
||||||
import schedule
|
import schedule
|
||||||
|
|
||||||
# Internal Packages
|
# Internal Packages
|
||||||
from khoj.configure import configure_routes, configure_server
|
from khoj.configure import configure_routes, initialize_server
|
||||||
from khoj.utils import state
|
from khoj.utils import state
|
||||||
from khoj.utils.cli import cli
|
from khoj.utils.cli import cli
|
||||||
from khoj.interface.desktop.main_window import MainWindow
|
from khoj.interface.desktop.main_window import MainWindow
|
||||||
|
@ -75,7 +75,7 @@ def run():
|
||||||
poll_task_scheduler()
|
poll_task_scheduler()
|
||||||
|
|
||||||
# Start Server
|
# Start Server
|
||||||
configure_server(args, required=False)
|
initialize_server(args.config, args.regenerate, required=False)
|
||||||
configure_routes(app)
|
configure_routes(app)
|
||||||
start_server(app, host=args.host, port=args.port, socket=args.socket)
|
start_server(app, host=args.host, port=args.port, socket=args.socket)
|
||||||
else:
|
else:
|
||||||
|
@ -93,7 +93,7 @@ def run():
|
||||||
tray.show()
|
tray.show()
|
||||||
|
|
||||||
# Setup Server
|
# Setup Server
|
||||||
configure_server(args, required=False)
|
initialize_server(args.config, args.regenerate, required=False)
|
||||||
configure_routes(app)
|
configure_routes(app)
|
||||||
server = ServerThread(app, args.host, args.port, args.socket)
|
server = ServerThread(app, args.host, args.port, args.socket)
|
||||||
|
|
||||||
|
|
|
@ -5,20 +5,20 @@ import time
|
||||||
import yaml
|
import yaml
|
||||||
import logging
|
import logging
|
||||||
import json
|
import json
|
||||||
from typing import List, Optional, Union
|
from typing import Iterable, List, Optional, Union
|
||||||
|
|
||||||
# External Packages
|
# External Packages
|
||||||
from fastapi import APIRouter, HTTPException, Header, Request
|
from fastapi import APIRouter, HTTPException, Header, Request
|
||||||
from sentence_transformers import util
|
from sentence_transformers import util
|
||||||
|
|
||||||
# Internal Packages
|
# Internal Packages
|
||||||
from khoj.configure import configure_content, configure_processor, configure_search
|
from khoj.configure import configure_processor, configure_server
|
||||||
from khoj.search_type import image_search, text_search
|
from khoj.search_type import image_search, text_search
|
||||||
from khoj.search_filter.date_filter import DateFilter
|
from khoj.search_filter.date_filter import DateFilter
|
||||||
from khoj.search_filter.file_filter import FileFilter
|
from khoj.search_filter.file_filter import FileFilter
|
||||||
from khoj.search_filter.word_filter import WordFilter
|
from khoj.search_filter.word_filter import WordFilter
|
||||||
from khoj.utils.config import TextSearchModel
|
from khoj.utils.config import TextSearchModel
|
||||||
from khoj.utils.helpers import log_telemetry, timer
|
from khoj.utils.helpers import timer
|
||||||
from khoj.utils.rawconfig import (
|
from khoj.utils.rawconfig import (
|
||||||
ContentConfig,
|
ContentConfig,
|
||||||
FullConfig,
|
FullConfig,
|
||||||
|
@ -524,34 +524,26 @@ def update(
|
||||||
referer: Optional[str] = Header(None),
|
referer: Optional[str] = Header(None),
|
||||||
host: Optional[str] = Header(None),
|
host: Optional[str] = Header(None),
|
||||||
):
|
):
|
||||||
|
if not state.config:
|
||||||
|
error_msg = f"🚨 Khoj is not configured.\nConfigure it via http://localhost:42110/config, plugins or by editing {state.config_file}."
|
||||||
|
logger.warning(error_msg)
|
||||||
|
raise HTTPException(status_code=500, detail=error_msg)
|
||||||
try:
|
try:
|
||||||
state.search_index_lock.acquire()
|
configure_server(state.config, regenerate=force or False, search_type=t)
|
||||||
try:
|
except Exception as e:
|
||||||
if state.config and state.config.search_type:
|
error_msg = f"🚨 Failed to update server via API: {e}"
|
||||||
state.search_models = configure_search(state.search_models, state.config.search_type)
|
logger.error(error_msg)
|
||||||
if state.search_models:
|
raise HTTPException(status_code=500, detail=error_msg)
|
||||||
state.content_index = configure_content(
|
|
||||||
state.content_index, state.config.content_type, state.search_models, regenerate=force or False, t=t
|
|
||||||
)
|
|
||||||
except Exception as e:
|
|
||||||
logger.error(e)
|
|
||||||
raise HTTPException(status_code=500, detail=str(e))
|
|
||||||
finally:
|
|
||||||
state.search_index_lock.release()
|
|
||||||
except ValueError as e:
|
|
||||||
logger.error(e)
|
|
||||||
raise HTTPException(status_code=500, detail=str(e))
|
|
||||||
else:
|
else:
|
||||||
logger.info("📬 Search index updated via API")
|
components = []
|
||||||
|
if state.search_models:
|
||||||
try:
|
components.append("Search models")
|
||||||
if state.config and state.config.processor:
|
if state.content_index:
|
||||||
state.processor_config = configure_processor(state.config.processor)
|
components.append("Content index")
|
||||||
except ValueError as e:
|
if state.processor_config:
|
||||||
logger.error(e)
|
components.append("Conversation processor")
|
||||||
raise HTTPException(status_code=500, detail=str(e))
|
components_msg = ", ".join(components)
|
||||||
else:
|
logger.info(f"📬 {components_msg} updated via API")
|
||||||
logger.info("📬 Processor reconfigured via API")
|
|
||||||
|
|
||||||
update_telemetry_state(
|
update_telemetry_state(
|
||||||
request=request,
|
request=request,
|
||||||
|
|
Loading…
Add table
Reference in a new issue