mirror of
https://github.com/onyx-dot-app/onyx.git
synced 2026-04-03 22:12:43 +00:00
Compare commits
2 Commits
cli/v0.2.0
...
nikg/std-e
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
3e8c76b9f2 | ||
|
|
09b6ce6a00 |
@@ -5,7 +5,6 @@ from typing import cast
|
||||
|
||||
from fastapi import APIRouter
|
||||
from fastapi import Depends
|
||||
from fastapi import HTTPException
|
||||
from sqlalchemy.orm import Session
|
||||
|
||||
from onyx.auth.users import current_admin_user
|
||||
@@ -28,6 +27,8 @@ from onyx.db.feedback import update_document_boost_for_user
|
||||
from onyx.db.feedback import update_document_hidden_for_user
|
||||
from onyx.db.index_attempt import cancel_indexing_attempts_for_ccpair
|
||||
from onyx.db.models import User
|
||||
from onyx.error_handling.error_codes import OnyxErrorCode
|
||||
from onyx.error_handling.exceptions import OnyxError
|
||||
from onyx.file_store.file_store import get_default_file_store
|
||||
from onyx.key_value_store.factory import get_kv_store
|
||||
from onyx.key_value_store.interface import KvKeyNotFoundError
|
||||
@@ -124,11 +125,11 @@ def validate_existing_genai_api_key(
|
||||
try:
|
||||
llm = get_default_llm(timeout=10)
|
||||
except ValueError:
|
||||
raise HTTPException(status_code=404, detail="LLM not setup")
|
||||
raise OnyxError(OnyxErrorCode.NOT_FOUND, "LLM not setup")
|
||||
|
||||
error = test_llm(llm)
|
||||
if error:
|
||||
raise HTTPException(status_code=400, detail=error)
|
||||
raise OnyxError(OnyxErrorCode.VALIDATION_ERROR, error)
|
||||
|
||||
# Mark check as successful
|
||||
curr_time = datetime.now(tz=timezone.utc)
|
||||
@@ -159,10 +160,7 @@ def create_deletion_attempt_for_connector_id(
|
||||
f"'{credential_id}' does not exist. Has it already been deleted?"
|
||||
)
|
||||
logger.error(error)
|
||||
raise HTTPException(
|
||||
status_code=404,
|
||||
detail=error,
|
||||
)
|
||||
raise OnyxError(OnyxErrorCode.CONNECTOR_NOT_FOUND, error)
|
||||
|
||||
# Cancel any scheduled indexing attempts
|
||||
cancel_indexing_attempts_for_ccpair(
|
||||
@@ -178,9 +176,9 @@ def create_deletion_attempt_for_connector_id(
|
||||
# connector_credential_pair=cc_pair, db_session=db_session
|
||||
# )
|
||||
# if deletion_attempt_disallowed_reason:
|
||||
# raise HTTPException(
|
||||
# status_code=400,
|
||||
# detail=deletion_attempt_disallowed_reason,
|
||||
# raise OnyxError(
|
||||
# OnyxErrorCode.VALIDATION_ERROR,
|
||||
# deletion_attempt_disallowed_reason,
|
||||
# )
|
||||
|
||||
# mark as deleting
|
||||
|
||||
@@ -2,8 +2,6 @@
|
||||
|
||||
from fastapi import APIRouter
|
||||
from fastapi import Depends
|
||||
from fastapi import HTTPException
|
||||
from fastapi import status
|
||||
from sqlalchemy.orm import Session
|
||||
|
||||
from onyx.auth.users import current_admin_user
|
||||
@@ -24,6 +22,8 @@ from onyx.db.discord_bot import update_discord_channel_config
|
||||
from onyx.db.discord_bot import update_guild_config
|
||||
from onyx.db.engine.sql_engine import get_session
|
||||
from onyx.db.models import User
|
||||
from onyx.error_handling.error_codes import OnyxErrorCode
|
||||
from onyx.error_handling.exceptions import OnyxError
|
||||
from onyx.server.manage.discord_bot.models import DiscordBotConfigCreateRequest
|
||||
from onyx.server.manage.discord_bot.models import DiscordBotConfigResponse
|
||||
from onyx.server.manage.discord_bot.models import DiscordChannelConfigResponse
|
||||
@@ -47,14 +47,14 @@ def _check_bot_config_api_access() -> None:
|
||||
- When DISCORD_BOT_TOKEN env var is set (managed via env)
|
||||
"""
|
||||
if AUTH_TYPE == AuthType.CLOUD:
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_403_FORBIDDEN,
|
||||
detail="Discord bot configuration is managed by Onyx on Cloud.",
|
||||
raise OnyxError(
|
||||
OnyxErrorCode.UNAUTHORIZED,
|
||||
"Discord bot configuration is managed by Onyx on Cloud.",
|
||||
)
|
||||
if DISCORD_BOT_TOKEN:
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_403_FORBIDDEN,
|
||||
detail="Discord bot is configured via environment variables. API access disabled.",
|
||||
raise OnyxError(
|
||||
OnyxErrorCode.UNAUTHORIZED,
|
||||
"Discord bot is configured via environment variables. API access disabled.",
|
||||
)
|
||||
|
||||
|
||||
@@ -92,9 +92,9 @@ def create_bot_request(
|
||||
bot_token=request.bot_token,
|
||||
)
|
||||
except ValueError:
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_409_CONFLICT,
|
||||
detail="Discord bot config already exists. Delete it first to create a new one.",
|
||||
raise OnyxError(
|
||||
OnyxErrorCode.CONFLICT,
|
||||
"Discord bot config already exists. Delete it first to create a new one.",
|
||||
)
|
||||
|
||||
db_session.commit()
|
||||
@@ -117,7 +117,7 @@ def delete_bot_config_endpoint(
|
||||
"""
|
||||
deleted = delete_discord_bot_config(db_session)
|
||||
if not deleted:
|
||||
raise HTTPException(status_code=404, detail="Bot config not found")
|
||||
raise OnyxError(OnyxErrorCode.NOT_FOUND, "Bot config not found")
|
||||
|
||||
# Also delete the service API key used by the Discord bot
|
||||
delete_discord_service_api_key(db_session)
|
||||
@@ -144,7 +144,7 @@ def delete_service_api_key_endpoint(
|
||||
"""
|
||||
deleted = delete_discord_service_api_key(db_session)
|
||||
if not deleted:
|
||||
raise HTTPException(status_code=404, detail="Service API key not found")
|
||||
raise OnyxError(OnyxErrorCode.NOT_FOUND, "Service API key not found")
|
||||
db_session.commit()
|
||||
return {"deleted": True}
|
||||
|
||||
@@ -189,7 +189,7 @@ def get_guild_config(
|
||||
"""Get specific guild config."""
|
||||
config = get_guild_config_by_internal_id(db_session, internal_id=config_id)
|
||||
if not config:
|
||||
raise HTTPException(status_code=404, detail="Guild config not found")
|
||||
raise OnyxError(OnyxErrorCode.NOT_FOUND, "Guild config not found")
|
||||
return DiscordGuildConfigResponse.model_validate(config)
|
||||
|
||||
|
||||
@@ -203,7 +203,7 @@ def update_guild_request(
|
||||
"""Update guild config."""
|
||||
config = get_guild_config_by_internal_id(db_session, internal_id=config_id)
|
||||
if not config:
|
||||
raise HTTPException(status_code=404, detail="Guild config not found")
|
||||
raise OnyxError(OnyxErrorCode.NOT_FOUND, "Guild config not found")
|
||||
|
||||
config = update_guild_config(
|
||||
db_session,
|
||||
@@ -228,7 +228,7 @@ def delete_guild_request(
|
||||
"""
|
||||
deleted = delete_guild_config(db_session, config_id)
|
||||
if not deleted:
|
||||
raise HTTPException(status_code=404, detail="Guild config not found")
|
||||
raise OnyxError(OnyxErrorCode.NOT_FOUND, "Guild config not found")
|
||||
|
||||
# On Cloud, delete service API key when all guilds are removed
|
||||
if AUTH_TYPE == AuthType.CLOUD:
|
||||
@@ -254,9 +254,9 @@ def list_channel_configs(
|
||||
"""List whitelisted channels for a guild."""
|
||||
guild_config = get_guild_config_by_internal_id(db_session, internal_id=config_id)
|
||||
if not guild_config:
|
||||
raise HTTPException(status_code=404, detail="Guild config not found")
|
||||
raise OnyxError(OnyxErrorCode.NOT_FOUND, "Guild config not found")
|
||||
if not guild_config.guild_id:
|
||||
raise HTTPException(status_code=400, detail="Guild not yet registered")
|
||||
raise OnyxError(OnyxErrorCode.VALIDATION_ERROR, "Guild not yet registered")
|
||||
|
||||
configs = get_channel_configs(db_session, config_id)
|
||||
return [DiscordChannelConfigResponse.model_validate(c) for c in configs]
|
||||
@@ -278,7 +278,7 @@ def update_channel_request(
|
||||
db_session, guild_config_id, channel_config_id
|
||||
)
|
||||
if not config:
|
||||
raise HTTPException(status_code=404, detail="Channel config not found")
|
||||
raise OnyxError(OnyxErrorCode.NOT_FOUND, "Channel config not found")
|
||||
|
||||
config = update_discord_channel_config(
|
||||
db_session,
|
||||
|
||||
@@ -3,7 +3,6 @@ import re
|
||||
|
||||
import requests
|
||||
from fastapi import APIRouter
|
||||
from fastapi import HTTPException
|
||||
|
||||
from onyx import __version__
|
||||
from onyx.auth.users import anonymous_user_enabled
|
||||
@@ -16,6 +15,8 @@ from onyx.configs.constants import DEV_VERSION_PATTERN
|
||||
from onyx.configs.constants import PUBLIC_API_TAGS
|
||||
from onyx.configs.constants import STABLE_VERSION_PATTERN
|
||||
from onyx.db.auth import get_user_count
|
||||
from onyx.error_handling.error_codes import OnyxErrorCode
|
||||
from onyx.error_handling.exceptions import OnyxError
|
||||
from onyx.server.manage.models import AllVersions
|
||||
from onyx.server.manage.models import AuthTypeResponse
|
||||
from onyx.server.manage.models import ContainerVersions
|
||||
@@ -104,14 +105,14 @@ def get_versions() -> AllVersions:
|
||||
|
||||
# Ensure we have at least one tag of each type
|
||||
if not dev_tags:
|
||||
raise HTTPException(
|
||||
status_code=500,
|
||||
detail="No valid dev versions found matching pattern v(number).(number).(number)-beta.(number)",
|
||||
raise OnyxError(
|
||||
OnyxErrorCode.INTERNAL_ERROR,
|
||||
"No valid dev versions found matching pattern v(number).(number).(number)-beta.(number)",
|
||||
)
|
||||
if not stable_tags:
|
||||
raise HTTPException(
|
||||
status_code=500,
|
||||
detail="No valid stable versions found matching pattern v(number).(number).(number)",
|
||||
raise OnyxError(
|
||||
OnyxErrorCode.INTERNAL_ERROR,
|
||||
"No valid stable versions found matching pattern v(number).(number).(number)",
|
||||
)
|
||||
|
||||
# Sort common tags and get the latest one
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
from fastapi import APIRouter
|
||||
from fastapi import Depends
|
||||
from fastapi import HTTPException
|
||||
from sqlalchemy.orm import Session
|
||||
|
||||
from onyx.auth.users import current_admin_user
|
||||
@@ -15,6 +14,8 @@ from onyx.db.llm import remove_llm_provider__no_commit
|
||||
from onyx.db.models import LLMProvider as LLMProviderModel
|
||||
from onyx.db.models import ModelConfiguration
|
||||
from onyx.db.models import User
|
||||
from onyx.error_handling.error_codes import OnyxErrorCode
|
||||
from onyx.error_handling.exceptions import OnyxError
|
||||
from onyx.image_gen.exceptions import ImageProviderCredentialsError
|
||||
from onyx.image_gen.factory import get_image_generation_provider
|
||||
from onyx.image_gen.factory import validate_credentials
|
||||
@@ -74,9 +75,9 @@ def _build_llm_provider_request(
|
||||
# Clone mode: Only use API key from source provider
|
||||
source_provider = db_session.get(LLMProviderModel, source_llm_provider_id)
|
||||
if not source_provider:
|
||||
raise HTTPException(
|
||||
status_code=404,
|
||||
detail=f"Source LLM provider with id {source_llm_provider_id} not found",
|
||||
raise OnyxError(
|
||||
OnyxErrorCode.NOT_FOUND,
|
||||
f"Source LLM provider with id {source_llm_provider_id} not found",
|
||||
)
|
||||
|
||||
_validate_llm_provider_change(
|
||||
@@ -110,9 +111,9 @@ def _build_llm_provider_request(
|
||||
)
|
||||
|
||||
if not provider:
|
||||
raise HTTPException(
|
||||
status_code=400,
|
||||
detail="No provider or source llm provided",
|
||||
raise OnyxError(
|
||||
OnyxErrorCode.VALIDATION_ERROR,
|
||||
"No provider or source llm provided",
|
||||
)
|
||||
|
||||
credentials = ImageGenerationProviderCredentials(
|
||||
@@ -124,9 +125,9 @@ def _build_llm_provider_request(
|
||||
)
|
||||
|
||||
if not validate_credentials(provider, credentials):
|
||||
raise HTTPException(
|
||||
status_code=400,
|
||||
detail=f"Incorrect credentials for {provider}",
|
||||
raise OnyxError(
|
||||
OnyxErrorCode.VALIDATION_ERROR,
|
||||
f"Incorrect credentials for {provider}",
|
||||
)
|
||||
|
||||
return LLMProviderUpsertRequest(
|
||||
@@ -215,9 +216,9 @@ def test_image_generation(
|
||||
LLMProviderModel, test_request.source_llm_provider_id
|
||||
)
|
||||
if not source_provider:
|
||||
raise HTTPException(
|
||||
status_code=404,
|
||||
detail=f"Source LLM provider with id {test_request.source_llm_provider_id} not found",
|
||||
raise OnyxError(
|
||||
OnyxErrorCode.NOT_FOUND,
|
||||
f"Source LLM provider with id {test_request.source_llm_provider_id} not found",
|
||||
)
|
||||
|
||||
_validate_llm_provider_change(
|
||||
@@ -236,9 +237,9 @@ def test_image_generation(
|
||||
provider = source_provider.provider
|
||||
|
||||
if provider is None:
|
||||
raise HTTPException(
|
||||
status_code=400,
|
||||
detail="No provider or source llm provided",
|
||||
raise OnyxError(
|
||||
OnyxErrorCode.VALIDATION_ERROR,
|
||||
"No provider or source llm provided",
|
||||
)
|
||||
|
||||
try:
|
||||
@@ -257,14 +258,14 @@ def test_image_generation(
|
||||
),
|
||||
)
|
||||
except ValueError:
|
||||
raise HTTPException(
|
||||
status_code=404,
|
||||
detail=f"Invalid image generation provider: {provider}",
|
||||
raise OnyxError(
|
||||
OnyxErrorCode.NOT_FOUND,
|
||||
f"Invalid image generation provider: {provider}",
|
||||
)
|
||||
except ImageProviderCredentialsError:
|
||||
raise HTTPException(
|
||||
status_code=401,
|
||||
detail="Invalid image generation credentials",
|
||||
raise OnyxError(
|
||||
OnyxErrorCode.UNAUTHENTICATED,
|
||||
"Invalid image generation credentials",
|
||||
)
|
||||
|
||||
quality = _get_test_quality_for_model(test_request.model_name)
|
||||
@@ -276,15 +277,15 @@ def test_image_generation(
|
||||
n=1,
|
||||
quality=quality,
|
||||
)
|
||||
except HTTPException:
|
||||
except OnyxError:
|
||||
raise
|
||||
except Exception as e:
|
||||
# Log only exception type to avoid exposing sensitive data
|
||||
# (LiteLLM errors may contain URLs with API keys or auth tokens)
|
||||
logger.warning(f"Image generation test failed: {type(e).__name__}")
|
||||
raise HTTPException(
|
||||
status_code=400,
|
||||
detail=f"Image generation test failed: {type(e).__name__}",
|
||||
raise OnyxError(
|
||||
OnyxErrorCode.VALIDATION_ERROR,
|
||||
f"Image generation test failed: {type(e).__name__}",
|
||||
)
|
||||
|
||||
|
||||
@@ -309,9 +310,9 @@ def create_config(
|
||||
db_session, config_create.image_provider_id
|
||||
)
|
||||
if existing_config:
|
||||
raise HTTPException(
|
||||
status_code=400,
|
||||
detail=f"ImageGenerationConfig with image_provider_id '{config_create.image_provider_id}' already exists",
|
||||
raise OnyxError(
|
||||
OnyxErrorCode.VALIDATION_ERROR,
|
||||
f"ImageGenerationConfig with image_provider_id '{config_create.image_provider_id}' already exists",
|
||||
)
|
||||
|
||||
try:
|
||||
@@ -345,10 +346,10 @@ def create_config(
|
||||
db_session.commit()
|
||||
db_session.refresh(config)
|
||||
return ImageGenerationConfigView.from_model(config)
|
||||
except HTTPException:
|
||||
except OnyxError:
|
||||
raise
|
||||
except Exception as e:
|
||||
raise HTTPException(status_code=400, detail=str(e))
|
||||
raise OnyxError(OnyxErrorCode.VALIDATION_ERROR, str(e))
|
||||
|
||||
|
||||
@admin_router.get("/config")
|
||||
@@ -373,9 +374,9 @@ def get_config_credentials(
|
||||
"""
|
||||
config = get_image_generation_config(db_session, image_provider_id)
|
||||
if not config:
|
||||
raise HTTPException(
|
||||
status_code=404,
|
||||
detail=f"ImageGenerationConfig with image_provider_id {image_provider_id} not found",
|
||||
raise OnyxError(
|
||||
OnyxErrorCode.NOT_FOUND,
|
||||
f"ImageGenerationConfig with image_provider_id {image_provider_id} not found",
|
||||
)
|
||||
|
||||
return ImageGenerationCredentials.from_model(config)
|
||||
@@ -401,9 +402,9 @@ def update_config(
|
||||
# 1. Get existing config
|
||||
existing_config = get_image_generation_config(db_session, image_provider_id)
|
||||
if not existing_config:
|
||||
raise HTTPException(
|
||||
status_code=404,
|
||||
detail=f"ImageGenerationConfig with image_provider_id {image_provider_id} not found",
|
||||
raise OnyxError(
|
||||
OnyxErrorCode.NOT_FOUND,
|
||||
f"ImageGenerationConfig with image_provider_id {image_provider_id} not found",
|
||||
)
|
||||
|
||||
old_llm_provider_id = existing_config.model_configuration.llm_provider_id
|
||||
@@ -472,10 +473,10 @@ def update_config(
|
||||
db_session.refresh(existing_config)
|
||||
return ImageGenerationConfigView.from_model(existing_config)
|
||||
|
||||
except HTTPException:
|
||||
except OnyxError:
|
||||
raise
|
||||
except Exception as e:
|
||||
raise HTTPException(status_code=400, detail=str(e))
|
||||
raise OnyxError(OnyxErrorCode.VALIDATION_ERROR, str(e))
|
||||
|
||||
|
||||
@admin_router.delete("/config/{image_provider_id}")
|
||||
@@ -489,9 +490,9 @@ def delete_config(
|
||||
# Get the config first to find the associated LLM provider
|
||||
existing_config = get_image_generation_config(db_session, image_provider_id)
|
||||
if not existing_config:
|
||||
raise HTTPException(
|
||||
status_code=404,
|
||||
detail=f"ImageGenerationConfig with image_provider_id {image_provider_id} not found",
|
||||
raise OnyxError(
|
||||
OnyxErrorCode.NOT_FOUND,
|
||||
f"ImageGenerationConfig with image_provider_id {image_provider_id} not found",
|
||||
)
|
||||
|
||||
llm_provider_id = existing_config.model_configuration.llm_provider_id
|
||||
@@ -503,10 +504,10 @@ def delete_config(
|
||||
remove_llm_provider__no_commit(db_session, llm_provider_id)
|
||||
|
||||
db_session.commit()
|
||||
except HTTPException:
|
||||
except OnyxError:
|
||||
raise
|
||||
except ValueError as e:
|
||||
raise HTTPException(status_code=404, detail=str(e))
|
||||
raise OnyxError(OnyxErrorCode.NOT_FOUND, str(e))
|
||||
|
||||
|
||||
@admin_router.post("/config/{image_provider_id}/default")
|
||||
@@ -519,7 +520,7 @@ def set_config_as_default(
|
||||
try:
|
||||
set_default_image_generation_config(db_session, image_provider_id)
|
||||
except ValueError as e:
|
||||
raise HTTPException(status_code=404, detail=str(e))
|
||||
raise OnyxError(OnyxErrorCode.NOT_FOUND, str(e))
|
||||
|
||||
|
||||
@admin_router.delete("/config/{image_provider_id}/default")
|
||||
@@ -532,4 +533,4 @@ def unset_config_as_default(
|
||||
try:
|
||||
unset_default_image_generation_config(db_session, image_provider_id)
|
||||
except ValueError as e:
|
||||
raise HTTPException(status_code=404, detail=str(e))
|
||||
raise OnyxError(OnyxErrorCode.NOT_FOUND, str(e))
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
from fastapi import APIRouter
|
||||
from fastapi import Depends
|
||||
from fastapi import HTTPException
|
||||
from fastapi import status
|
||||
from sqlalchemy.orm import Session
|
||||
|
||||
from onyx.auth.users import current_admin_user
|
||||
@@ -27,6 +25,8 @@ from onyx.db.search_settings import update_current_search_settings
|
||||
from onyx.db.search_settings import update_search_settings_status
|
||||
from onyx.document_index.factory import get_all_document_indices
|
||||
from onyx.document_index.factory import get_default_document_index
|
||||
from onyx.error_handling.error_codes import OnyxErrorCode
|
||||
from onyx.error_handling.exceptions import OnyxError
|
||||
from onyx.file_processing.unstructured import delete_unstructured_api_key
|
||||
from onyx.file_processing.unstructured import get_unstructured_api_key
|
||||
from onyx.file_processing.unstructured import update_unstructured_api_key
|
||||
@@ -58,9 +58,9 @@ def set_new_search_settings(
|
||||
|
||||
# Disallow contextual RAG for cloud deployments.
|
||||
if MULTI_TENANT and search_settings_new.enable_contextual_rag:
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_400_BAD_REQUEST,
|
||||
detail="Contextual RAG disabled in Onyx Cloud",
|
||||
raise OnyxError(
|
||||
OnyxErrorCode.VALIDATION_ERROR,
|
||||
"Contextual RAG disabled in Onyx Cloud",
|
||||
)
|
||||
|
||||
# Validate cloud provider exists or create new LiteLLM provider.
|
||||
@@ -70,9 +70,9 @@ def set_new_search_settings(
|
||||
)
|
||||
|
||||
if cloud_provider is None:
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_400_BAD_REQUEST,
|
||||
detail=f"No embedding provider exists for cloud embedding type {search_settings_new.provider_type}",
|
||||
raise OnyxError(
|
||||
OnyxErrorCode.VALIDATION_ERROR,
|
||||
f"No embedding provider exists for cloud embedding type {search_settings_new.provider_type}",
|
||||
)
|
||||
|
||||
validate_contextual_rag_model(
|
||||
@@ -188,7 +188,7 @@ def delete_search_settings_endpoint(
|
||||
search_settings_id=deletion_request.search_settings_id,
|
||||
)
|
||||
except ValueError as e:
|
||||
raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail=str(e))
|
||||
raise OnyxError(OnyxErrorCode.VALIDATION_ERROR, str(e))
|
||||
|
||||
|
||||
@router.get("/get-current-search-settings")
|
||||
@@ -238,9 +238,9 @@ def update_saved_search_settings(
|
||||
) -> None:
|
||||
# Disallow contextual RAG for cloud deployments
|
||||
if MULTI_TENANT and search_settings.enable_contextual_rag:
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_400_BAD_REQUEST,
|
||||
detail="Contextual RAG disabled in Onyx Cloud",
|
||||
raise OnyxError(
|
||||
OnyxErrorCode.VALIDATION_ERROR,
|
||||
"Contextual RAG disabled in Onyx Cloud",
|
||||
)
|
||||
|
||||
validate_contextual_rag_model(
|
||||
@@ -294,7 +294,7 @@ def validate_contextual_rag_model(
|
||||
model_name=model_name,
|
||||
db_session=db_session,
|
||||
):
|
||||
raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail=error_msg)
|
||||
raise OnyxError(OnyxErrorCode.VALIDATION_ERROR, error_msg)
|
||||
|
||||
|
||||
def _validate_contextual_rag_model(
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
from fastapi import APIRouter
|
||||
from fastapi import Depends
|
||||
from fastapi import HTTPException
|
||||
from sqlalchemy.orm import Session
|
||||
|
||||
from onyx.auth.users import current_admin_user
|
||||
@@ -21,6 +20,8 @@ from onyx.db.slack_channel_config import fetch_slack_channel_configs
|
||||
from onyx.db.slack_channel_config import insert_slack_channel_config
|
||||
from onyx.db.slack_channel_config import remove_slack_channel_config
|
||||
from onyx.db.slack_channel_config import update_slack_channel_config
|
||||
from onyx.error_handling.error_codes import OnyxErrorCode
|
||||
from onyx.error_handling.exceptions import OnyxError
|
||||
from onyx.onyxbot.slack.config import validate_channel_name
|
||||
from onyx.server.manage.models import SlackBot
|
||||
from onyx.server.manage.models import SlackBotCreationRequest
|
||||
@@ -63,10 +64,7 @@ def _form_channel_config(
|
||||
current_slack_bot_id=slack_channel_config_creation_request.slack_bot_id,
|
||||
)
|
||||
except ValueError as e:
|
||||
raise HTTPException(
|
||||
status_code=400,
|
||||
detail=str(e),
|
||||
)
|
||||
raise OnyxError(OnyxErrorCode.VALIDATION_ERROR, str(e))
|
||||
|
||||
if respond_tag_only and respond_member_group_list:
|
||||
raise ValueError(
|
||||
@@ -123,10 +121,7 @@ def create_slack_channel_config(
|
||||
)
|
||||
|
||||
if channel_config["channel_name"] is None:
|
||||
raise HTTPException(
|
||||
status_code=400,
|
||||
detail="Channel name is required",
|
||||
)
|
||||
raise OnyxError(OnyxErrorCode.VALIDATION_ERROR, "Channel name is required")
|
||||
|
||||
persona_id = None
|
||||
if slack_channel_config_creation_request.persona_id is not None:
|
||||
@@ -171,10 +166,7 @@ def patch_slack_channel_config(
|
||||
db_session=db_session, slack_channel_config_id=slack_channel_config_id
|
||||
)
|
||||
if existing_slack_channel_config is None:
|
||||
raise HTTPException(
|
||||
status_code=404,
|
||||
detail="Slack channel config not found",
|
||||
)
|
||||
raise OnyxError(OnyxErrorCode.NOT_FOUND, "Slack channel config not found")
|
||||
|
||||
existing_persona_id = existing_slack_channel_config.persona_id
|
||||
if existing_persona_id is not None:
|
||||
|
||||
@@ -13,7 +13,6 @@ from email_validator import validate_email
|
||||
from fastapi import APIRouter
|
||||
from fastapi import Body
|
||||
from fastapi import Depends
|
||||
from fastapi import HTTPException
|
||||
from fastapi import Query
|
||||
from fastapi import Request
|
||||
from fastapi.responses import StreamingResponse
|
||||
@@ -73,6 +72,8 @@ from onyx.db.users import get_page_of_filtered_users
|
||||
from onyx.db.users import get_total_filtered_users_count
|
||||
from onyx.db.users import get_user_by_email
|
||||
from onyx.db.users import validate_user_role_update
|
||||
from onyx.error_handling.error_codes import OnyxErrorCode
|
||||
from onyx.error_handling.exceptions import OnyxError
|
||||
from onyx.key_value_store.factory import get_kv_store
|
||||
from onyx.redis.redis_pool import get_raw_redis_client
|
||||
from onyx.server.documents.models import PaginatedReturn
|
||||
@@ -124,7 +125,7 @@ def set_user_role(
|
||||
email=user_role_update_request.user_email, db_session=db_session
|
||||
)
|
||||
if not user_to_update:
|
||||
raise HTTPException(status_code=404, detail="User not found")
|
||||
raise OnyxError(OnyxErrorCode.USER_NOT_FOUND, "User not found")
|
||||
|
||||
current_role = user_to_update.role
|
||||
requested_role = user_role_update_request.new_role
|
||||
@@ -139,9 +140,9 @@ def set_user_role(
|
||||
)
|
||||
|
||||
if user_to_update.id == current_user.id:
|
||||
raise HTTPException(
|
||||
status_code=400,
|
||||
detail="An admin cannot demote themselves from admin role!",
|
||||
raise OnyxError(
|
||||
OnyxErrorCode.VALIDATION_ERROR,
|
||||
"An admin cannot demote themselves from admin role!",
|
||||
)
|
||||
|
||||
if requested_role == UserRole.CURATOR:
|
||||
@@ -386,9 +387,9 @@ def bulk_invite_users(
|
||||
new_invited_emails.append(email_info.normalized)
|
||||
|
||||
except (EmailUndeliverableError, EmailNotValidError) as e:
|
||||
raise HTTPException(
|
||||
status_code=400,
|
||||
detail=f"Invalid email address: {email} - {str(e)}",
|
||||
raise OnyxError(
|
||||
OnyxErrorCode.VALIDATION_ERROR,
|
||||
f"Invalid email address: {email} - {str(e)}",
|
||||
)
|
||||
|
||||
# Count only new users (not already invited or existing) that need seats
|
||||
@@ -405,9 +406,9 @@ def bulk_invite_users(
|
||||
if MULTI_TENANT and is_tenant_on_trial_fn(tenant_id):
|
||||
current_invited = len(already_invited)
|
||||
if current_invited + len(emails_needing_seats) > NUM_FREE_TRIAL_USER_INVITES:
|
||||
raise HTTPException(
|
||||
status_code=403,
|
||||
detail="You have hit your invite limit. "
|
||||
raise OnyxError(
|
||||
OnyxErrorCode.SEAT_LIMIT_EXCEEDED,
|
||||
"You have hit your invite limit. "
|
||||
"Please upgrade for unlimited invites.",
|
||||
)
|
||||
|
||||
@@ -502,14 +503,16 @@ def deactivate_user_api(
|
||||
db_session: Session = Depends(get_session),
|
||||
) -> None:
|
||||
if current_user.email == user_email.user_email:
|
||||
raise HTTPException(status_code=400, detail="You cannot deactivate yourself")
|
||||
raise OnyxError(
|
||||
OnyxErrorCode.VALIDATION_ERROR, "You cannot deactivate yourself"
|
||||
)
|
||||
|
||||
user_to_deactivate = get_user_by_email(
|
||||
email=user_email.user_email, db_session=db_session
|
||||
)
|
||||
|
||||
if not user_to_deactivate:
|
||||
raise HTTPException(status_code=404, detail="User not found")
|
||||
raise OnyxError(OnyxErrorCode.USER_NOT_FOUND, "User not found")
|
||||
|
||||
if user_to_deactivate.is_active is False:
|
||||
logger.warning("{} is already deactivated".format(user_to_deactivate.email))
|
||||
@@ -534,14 +537,15 @@ async def delete_user(
|
||||
email=user_email.user_email, db_session=db_session
|
||||
)
|
||||
if not user_to_delete:
|
||||
raise HTTPException(status_code=404, detail="User not found")
|
||||
raise OnyxError(OnyxErrorCode.USER_NOT_FOUND, "User not found")
|
||||
|
||||
if user_to_delete.is_active is True:
|
||||
logger.warning(
|
||||
"{} must be deactivated before deleting".format(user_to_delete.email)
|
||||
)
|
||||
raise HTTPException(
|
||||
status_code=400, detail="User must be deactivated before deleting"
|
||||
raise OnyxError(
|
||||
OnyxErrorCode.VALIDATION_ERROR,
|
||||
"User must be deactivated before deleting",
|
||||
)
|
||||
|
||||
# Detach the user from the current session
|
||||
@@ -565,7 +569,7 @@ async def delete_user(
|
||||
except Exception as e:
|
||||
db_session.rollback()
|
||||
logger.error(f"Error deleting user {user_to_delete.email}: {str(e)}")
|
||||
raise HTTPException(status_code=500, detail="Error deleting user")
|
||||
raise OnyxError(OnyxErrorCode.INTERNAL_ERROR, "Error deleting user")
|
||||
|
||||
|
||||
@router.patch("/manage/admin/activate-user", tags=PUBLIC_API_TAGS)
|
||||
@@ -578,7 +582,7 @@ def activate_user_api(
|
||||
email=user_email.user_email, db_session=db_session
|
||||
)
|
||||
if not user_to_activate:
|
||||
raise HTTPException(status_code=404, detail="User not found")
|
||||
raise OnyxError(OnyxErrorCode.USER_NOT_FOUND, "User not found")
|
||||
|
||||
if user_to_activate.is_active is True:
|
||||
logger.warning("{} is already activated".format(user_to_activate.email))
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
import requests
|
||||
from fastapi import HTTPException
|
||||
|
||||
from onyx.configs.constants import SLACK_USER_TOKEN_PREFIX
|
||||
from onyx.error_handling.error_codes import OnyxErrorCode
|
||||
from onyx.error_handling.exceptions import OnyxError
|
||||
|
||||
SLACK_API_URL = "https://slack.com/api/auth.test"
|
||||
SLACK_CONNECTIONS_OPEN_URL = "https://slack.com/api/apps.connections.open"
|
||||
@@ -12,15 +13,15 @@ def validate_bot_token(bot_token: str) -> bool:
|
||||
response = requests.post(SLACK_API_URL, headers=headers)
|
||||
|
||||
if response.status_code != 200:
|
||||
raise HTTPException(
|
||||
status_code=500, detail="Error communicating with Slack API."
|
||||
raise OnyxError(
|
||||
OnyxErrorCode.INTERNAL_ERROR, "Error communicating with Slack API."
|
||||
)
|
||||
|
||||
data = response.json()
|
||||
if not data.get("ok", False):
|
||||
raise HTTPException(
|
||||
status_code=400,
|
||||
detail=f"Invalid bot token: {data.get('error', 'Unknown error')}",
|
||||
raise OnyxError(
|
||||
OnyxErrorCode.VALIDATION_ERROR,
|
||||
f"Invalid bot token: {data.get('error', 'Unknown error')}",
|
||||
)
|
||||
|
||||
return True
|
||||
@@ -31,15 +32,15 @@ def validate_app_token(app_token: str) -> bool:
|
||||
response = requests.post(SLACK_CONNECTIONS_OPEN_URL, headers=headers)
|
||||
|
||||
if response.status_code != 200:
|
||||
raise HTTPException(
|
||||
status_code=500, detail="Error communicating with Slack API."
|
||||
raise OnyxError(
|
||||
OnyxErrorCode.INTERNAL_ERROR, "Error communicating with Slack API."
|
||||
)
|
||||
|
||||
data = response.json()
|
||||
if not data.get("ok", False):
|
||||
raise HTTPException(
|
||||
status_code=400,
|
||||
detail=f"Invalid app token: {data.get('error', 'Unknown error')}",
|
||||
raise OnyxError(
|
||||
OnyxErrorCode.VALIDATION_ERROR,
|
||||
f"Invalid app token: {data.get('error', 'Unknown error')}",
|
||||
)
|
||||
|
||||
return True
|
||||
@@ -54,16 +55,16 @@ def validate_user_token(user_token: str | None) -> None:
|
||||
Returns:
|
||||
None is valid and will return successfully.
|
||||
Raises:
|
||||
HTTPException: If the token is invalid or missing required fields
|
||||
OnyxError: If the token is invalid or missing required fields
|
||||
"""
|
||||
if not user_token:
|
||||
# user_token is optional, so None or empty string is valid
|
||||
return
|
||||
|
||||
if not user_token.startswith(SLACK_USER_TOKEN_PREFIX):
|
||||
raise HTTPException(
|
||||
status_code=400,
|
||||
detail=f"Invalid user token format. User OAuth tokens must start with '{SLACK_USER_TOKEN_PREFIX}'",
|
||||
raise OnyxError(
|
||||
OnyxErrorCode.VALIDATION_ERROR,
|
||||
f"Invalid user token format. User OAuth tokens must start with '{SLACK_USER_TOKEN_PREFIX}'",
|
||||
)
|
||||
|
||||
# Test the token with Slack API to ensure it's valid
|
||||
@@ -71,13 +72,13 @@ def validate_user_token(user_token: str | None) -> None:
|
||||
response = requests.post(SLACK_API_URL, headers=headers)
|
||||
|
||||
if response.status_code != 200:
|
||||
raise HTTPException(
|
||||
status_code=500, detail="Error communicating with Slack API."
|
||||
raise OnyxError(
|
||||
OnyxErrorCode.INTERNAL_ERROR, "Error communicating with Slack API."
|
||||
)
|
||||
|
||||
data = response.json()
|
||||
if not data.get("ok", False):
|
||||
raise HTTPException(
|
||||
status_code=400,
|
||||
detail=f"Invalid user token: {data.get('error', 'Unknown error')}",
|
||||
raise OnyxError(
|
||||
OnyxErrorCode.VALIDATION_ERROR,
|
||||
f"Invalid user token: {data.get('error', 'Unknown error')}",
|
||||
)
|
||||
|
||||
@@ -2,7 +2,6 @@ from __future__ import annotations
|
||||
|
||||
from fastapi import APIRouter
|
||||
from fastapi import Depends
|
||||
from fastapi import HTTPException
|
||||
from fastapi import Response
|
||||
from sqlalchemy.dialects.postgresql import insert
|
||||
from sqlalchemy.orm import Session
|
||||
@@ -26,6 +25,8 @@ from onyx.db.web_search import set_active_web_content_provider
|
||||
from onyx.db.web_search import set_active_web_search_provider
|
||||
from onyx.db.web_search import upsert_web_content_provider
|
||||
from onyx.db.web_search import upsert_web_search_provider
|
||||
from onyx.error_handling.error_codes import OnyxErrorCode
|
||||
from onyx.error_handling.exceptions import OnyxError
|
||||
from onyx.server.manage.web_search.models import WebContentProviderTestRequest
|
||||
from onyx.server.manage.web_search.models import WebContentProviderUpsertRequest
|
||||
from onyx.server.manage.web_search.models import WebContentProviderView
|
||||
@@ -86,9 +87,9 @@ def upsert_search_provider_endpoint(
|
||||
and request.id is not None
|
||||
and existing_by_name.id != request.id
|
||||
):
|
||||
raise HTTPException(
|
||||
status_code=400,
|
||||
detail=f"A search provider named '{request.name}' already exists.",
|
||||
raise OnyxError(
|
||||
OnyxErrorCode.VALIDATION_ERROR,
|
||||
f"A search provider named '{request.name}' already exists.",
|
||||
)
|
||||
|
||||
provider = upsert_web_search_provider(
|
||||
@@ -193,16 +194,16 @@ def test_search_provider(
|
||||
request.provider_type, db_session
|
||||
)
|
||||
if existing_provider is None or not existing_provider.api_key:
|
||||
raise HTTPException(
|
||||
status_code=400,
|
||||
detail="No stored API key found for this provider type.",
|
||||
raise OnyxError(
|
||||
OnyxErrorCode.VALIDATION_ERROR,
|
||||
"No stored API key found for this provider type.",
|
||||
)
|
||||
api_key = existing_provider.api_key.get_value(apply_mask=False)
|
||||
|
||||
if requires_key and not api_key:
|
||||
raise HTTPException(
|
||||
status_code=400,
|
||||
detail="API key is required. Either provide api_key or set use_stored_key to true.",
|
||||
raise OnyxError(
|
||||
OnyxErrorCode.VALIDATION_ERROR,
|
||||
"API key is required. Either provide api_key or set use_stored_key to true.",
|
||||
)
|
||||
|
||||
try:
|
||||
@@ -212,20 +213,21 @@ def test_search_provider(
|
||||
config=request.config or {},
|
||||
)
|
||||
except ValueError as exc:
|
||||
raise HTTPException(status_code=400, detail=str(exc)) from exc
|
||||
raise OnyxError(OnyxErrorCode.VALIDATION_ERROR, str(exc)) from exc
|
||||
|
||||
if provider is None:
|
||||
raise HTTPException(
|
||||
status_code=400, detail="Unable to build provider configuration."
|
||||
raise OnyxError(
|
||||
OnyxErrorCode.VALIDATION_ERROR,
|
||||
"Unable to build provider configuration.",
|
||||
)
|
||||
|
||||
# Run the API client's test_connection method to ensure the connection is valid.
|
||||
try:
|
||||
return provider.test_connection()
|
||||
except HTTPException:
|
||||
except OnyxError:
|
||||
raise
|
||||
except Exception as e:
|
||||
raise HTTPException(status_code=400, detail=str(e)) from e
|
||||
raise OnyxError(OnyxErrorCode.VALIDATION_ERROR, str(e)) from e
|
||||
|
||||
|
||||
@admin_router.get("/content-providers", response_model=list[WebContentProviderView])
|
||||
@@ -259,9 +261,9 @@ def upsert_content_provider_endpoint(
|
||||
and request.id is not None
|
||||
and existing_by_name.id != request.id
|
||||
):
|
||||
raise HTTPException(
|
||||
status_code=400,
|
||||
detail=f"A content provider named '{request.name}' already exists.",
|
||||
raise OnyxError(
|
||||
OnyxErrorCode.VALIDATION_ERROR,
|
||||
f"A content provider named '{request.name}' already exists.",
|
||||
)
|
||||
|
||||
provider = upsert_web_content_provider(
|
||||
@@ -379,9 +381,9 @@ def test_content_provider(
|
||||
request.provider_type, db_session
|
||||
)
|
||||
if existing_provider is None or not existing_provider.api_key:
|
||||
raise HTTPException(
|
||||
status_code=400,
|
||||
detail="No stored API key found for this provider type.",
|
||||
raise OnyxError(
|
||||
OnyxErrorCode.VALIDATION_ERROR,
|
||||
"No stored API key found for this provider type.",
|
||||
)
|
||||
if MULTI_TENANT:
|
||||
stored_base_url = (
|
||||
@@ -389,17 +391,17 @@ def test_content_provider(
|
||||
)
|
||||
request_base_url = request.config.base_url
|
||||
if request_base_url != stored_base_url:
|
||||
raise HTTPException(
|
||||
status_code=400,
|
||||
detail="Base URL cannot differ from stored provider when using stored API key",
|
||||
raise OnyxError(
|
||||
OnyxErrorCode.VALIDATION_ERROR,
|
||||
"Base URL cannot differ from stored provider when using stored API key",
|
||||
)
|
||||
|
||||
api_key = existing_provider.api_key.get_value(apply_mask=False)
|
||||
|
||||
if not api_key:
|
||||
raise HTTPException(
|
||||
status_code=400,
|
||||
detail="API key is required. Either provide api_key or set use_stored_key to true.",
|
||||
raise OnyxError(
|
||||
OnyxErrorCode.VALIDATION_ERROR,
|
||||
"API key is required. Either provide api_key or set use_stored_key to true.",
|
||||
)
|
||||
|
||||
try:
|
||||
@@ -409,11 +411,12 @@ def test_content_provider(
|
||||
config=request.config,
|
||||
)
|
||||
except ValueError as exc:
|
||||
raise HTTPException(status_code=400, detail=str(exc)) from exc
|
||||
raise OnyxError(OnyxErrorCode.VALIDATION_ERROR, str(exc)) from exc
|
||||
|
||||
if provider is None:
|
||||
raise HTTPException(
|
||||
status_code=400, detail="Unable to build provider configuration."
|
||||
raise OnyxError(
|
||||
OnyxErrorCode.VALIDATION_ERROR,
|
||||
"Unable to build provider configuration.",
|
||||
)
|
||||
|
||||
# Actually test the API key by making a real content fetch call
|
||||
@@ -425,11 +428,11 @@ def test_content_provider(
|
||||
if not test_results or not any(
|
||||
result.scrape_successful for result in test_results
|
||||
):
|
||||
raise HTTPException(
|
||||
status_code=400,
|
||||
detail="API key validation failed: content fetch returned no results.",
|
||||
raise OnyxError(
|
||||
OnyxErrorCode.VALIDATION_ERROR,
|
||||
"API key validation failed: content fetch returned no results.",
|
||||
)
|
||||
except HTTPException:
|
||||
except OnyxError:
|
||||
raise
|
||||
except Exception as e:
|
||||
error_msg = str(e)
|
||||
@@ -438,13 +441,13 @@ def test_content_provider(
|
||||
or "key" in error_msg.lower()
|
||||
or "auth" in error_msg.lower()
|
||||
):
|
||||
raise HTTPException(
|
||||
status_code=400,
|
||||
detail=f"Invalid API key: {error_msg}",
|
||||
raise OnyxError(
|
||||
OnyxErrorCode.VALIDATION_ERROR,
|
||||
f"Invalid API key: {error_msg}",
|
||||
) from e
|
||||
raise HTTPException(
|
||||
status_code=400,
|
||||
detail=f"API key validation failed: {error_msg}",
|
||||
raise OnyxError(
|
||||
OnyxErrorCode.VALIDATION_ERROR,
|
||||
f"API key validation failed: {error_msg}",
|
||||
) from e
|
||||
|
||||
logger.info(
|
||||
|
||||
Reference in New Issue
Block a user