mirror of
https://github.com/danswer-ai/danswer.git
synced 2025-05-02 16:00:34 +02:00
129 lines
4.4 KiB
Python
129 lines
4.4 KiB
Python
from typing import cast
|
|
|
|
from fastapi import APIRouter
|
|
from fastapi import Depends
|
|
from sqlalchemy.exc import SQLAlchemyError
|
|
from sqlalchemy.orm import Session
|
|
|
|
from onyx.auth.users import current_admin_user
|
|
from onyx.auth.users import current_user
|
|
from onyx.auth.users import is_user_admin
|
|
from onyx.configs.constants import KV_REINDEX_KEY
|
|
from onyx.configs.constants import NotificationType
|
|
from onyx.db.engine import get_session
|
|
from onyx.db.models import User
|
|
from onyx.db.notification import create_notification
|
|
from onyx.db.notification import dismiss_all_notifications
|
|
from onyx.db.notification import get_notifications
|
|
from onyx.db.notification import update_notification_last_shown
|
|
from onyx.key_value_store.factory import get_kv_store
|
|
from onyx.key_value_store.interface import KvKeyNotFoundError
|
|
from onyx.server.settings.models import Notification
|
|
from onyx.server.settings.models import Settings
|
|
from onyx.server.settings.models import UserSettings
|
|
from onyx.server.settings.store import load_settings
|
|
from onyx.server.settings.store import store_settings
|
|
from onyx.utils.logger import setup_logger
|
|
|
|
logger = setup_logger()
|
|
|
|
admin_router = APIRouter(prefix="/admin/settings")
|
|
basic_router = APIRouter(prefix="/settings")
|
|
|
|
|
|
@admin_router.put("")
|
|
def put_settings(
|
|
settings: Settings, _: User | None = Depends(current_admin_user)
|
|
) -> None:
|
|
store_settings(settings)
|
|
|
|
|
|
@basic_router.get("")
|
|
def fetch_settings(
|
|
user: User | None = Depends(current_user),
|
|
db_session: Session = Depends(get_session),
|
|
) -> UserSettings:
|
|
"""Settings and notifications are stuffed into this single endpoint to reduce number of
|
|
Postgres calls"""
|
|
general_settings = load_settings()
|
|
settings_notifications = get_settings_notifications(user, db_session)
|
|
|
|
try:
|
|
kv_store = get_kv_store()
|
|
needs_reindexing = cast(bool, kv_store.load(KV_REINDEX_KEY))
|
|
except KvKeyNotFoundError:
|
|
needs_reindexing = False
|
|
|
|
return UserSettings(
|
|
**general_settings.model_dump(),
|
|
notifications=settings_notifications,
|
|
needs_reindexing=needs_reindexing,
|
|
)
|
|
|
|
|
|
def get_settings_notifications(
|
|
user: User | None, db_session: Session
|
|
) -> list[Notification]:
|
|
"""Get notifications for settings page, including product gating and reindex notifications"""
|
|
# Check for product gating notification
|
|
product_notif = get_notifications(
|
|
user=None,
|
|
notif_type=NotificationType.TRIAL_ENDS_TWO_DAYS,
|
|
db_session=db_session,
|
|
)
|
|
notifications = [Notification.from_model(product_notif[0])] if product_notif else []
|
|
|
|
# Only show reindex notifications to admins
|
|
is_admin = is_user_admin(user)
|
|
if not is_admin:
|
|
return notifications
|
|
|
|
# Check if reindexing is needed
|
|
kv_store = get_kv_store()
|
|
try:
|
|
needs_index = cast(bool, kv_store.load(KV_REINDEX_KEY))
|
|
if not needs_index:
|
|
dismiss_all_notifications(
|
|
notif_type=NotificationType.REINDEX, db_session=db_session
|
|
)
|
|
return notifications
|
|
except KvKeyNotFoundError:
|
|
# If something goes wrong and the flag is gone, better to not start a reindexing
|
|
# it's a heavyweight long running job and maybe this flag is cleaned up later
|
|
logger.warning("Could not find reindex flag")
|
|
return notifications
|
|
|
|
try:
|
|
# Need a transaction in order to prevent under-counting current notifications
|
|
reindex_notifs = get_notifications(
|
|
user=user, notif_type=NotificationType.REINDEX, db_session=db_session
|
|
)
|
|
|
|
if not reindex_notifs:
|
|
notif = create_notification(
|
|
user_id=user.id if user else None,
|
|
notif_type=NotificationType.REINDEX,
|
|
db_session=db_session,
|
|
)
|
|
db_session.flush()
|
|
db_session.commit()
|
|
|
|
notifications.append(Notification.from_model(notif))
|
|
return notifications
|
|
|
|
if len(reindex_notifs) > 1:
|
|
logger.error("User has multiple reindex notifications")
|
|
|
|
reindex_notif = reindex_notifs[0]
|
|
update_notification_last_shown(
|
|
notification=reindex_notif, db_session=db_session
|
|
)
|
|
|
|
db_session.commit()
|
|
notifications.append(Notification.from_model(reindex_notif))
|
|
return notifications
|
|
except SQLAlchemyError:
|
|
logger.exception("Error while processing notifications")
|
|
db_session.rollback()
|
|
return notifications
|