mirror of
https://github.com/onyx-dot-app/onyx.git
synced 2026-03-16 13:12:41 +00:00
Compare commits
1 Commits
v3.0.0
...
nikg/std-e
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e0c957fdb2 |
@@ -2,7 +2,6 @@
|
||||
|
||||
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
|
||||
@@ -10,6 +9,8 @@ from onyx.db.engine.sql_engine import get_session
|
||||
from onyx.db.models import User
|
||||
from onyx.db.persona import get_default_assistant
|
||||
from onyx.db.persona import update_default_assistant_configuration
|
||||
from onyx.error_handling.error_codes import OnyxErrorCode
|
||||
from onyx.error_handling.exceptions import OnyxError
|
||||
from onyx.prompts.chat_prompts import DEFAULT_SYSTEM_PROMPT
|
||||
from onyx.server.features.default_assistant.models import DefaultAssistantConfiguration
|
||||
from onyx.server.features.default_assistant.models import DefaultAssistantUpdateRequest
|
||||
@@ -32,7 +33,7 @@ def get_default_assistant_configuration(
|
||||
"""
|
||||
persona = get_default_assistant(db_session)
|
||||
if not persona:
|
||||
raise HTTPException(status_code=404, detail="Default assistant not found")
|
||||
raise OnyxError(OnyxErrorCode.PERSONA_NOT_FOUND, "Default assistant not found")
|
||||
|
||||
# Extract DB tool IDs from the persona's tools
|
||||
tool_ids = [tool.id for tool in persona.tools]
|
||||
@@ -86,5 +87,5 @@ def update_default_assistant(
|
||||
|
||||
except ValueError as e:
|
||||
if "Default assistant not found" in str(e):
|
||||
raise HTTPException(status_code=404, detail=str(e))
|
||||
raise HTTPException(status_code=400, detail=str(e))
|
||||
raise OnyxError(OnyxErrorCode.PERSONA_NOT_FOUND, str(e))
|
||||
raise OnyxError(OnyxErrorCode.VALIDATION_ERROR, str(e))
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
from fastapi import APIRouter
|
||||
from fastapi import Depends
|
||||
from fastapi import HTTPException
|
||||
from fastapi import Query
|
||||
from sqlalchemy.orm import Session
|
||||
|
||||
@@ -19,6 +18,8 @@ from onyx.db.document_set import mark_document_set_as_to_be_deleted
|
||||
from onyx.db.document_set import update_document_set
|
||||
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.features.document_set.models import CheckDocSetPublicRequest
|
||||
from onyx.server.features.document_set.models import CheckDocSetPublicResponse
|
||||
from onyx.server.features.document_set.models import DocumentSetCreationRequest
|
||||
@@ -54,7 +55,7 @@ def create_document_set(
|
||||
db_session=db_session,
|
||||
)
|
||||
except Exception as e:
|
||||
raise HTTPException(status_code=400, detail=str(e))
|
||||
raise OnyxError(OnyxErrorCode.VALIDATION_ERROR, str(e))
|
||||
|
||||
if not DISABLE_VECTOR_DB:
|
||||
client_app.send_task(
|
||||
@@ -75,9 +76,9 @@ def patch_document_set(
|
||||
) -> None:
|
||||
document_set = get_document_set_by_id(db_session, document_set_update_request.id)
|
||||
if document_set is None:
|
||||
raise HTTPException(
|
||||
status_code=404,
|
||||
detail=f"Document set {document_set_update_request.id} does not exist",
|
||||
raise OnyxError(
|
||||
OnyxErrorCode.NOT_FOUND,
|
||||
f"Document set {document_set_update_request.id} does not exist",
|
||||
)
|
||||
|
||||
fetch_ee_implementation_or_noop(
|
||||
@@ -97,7 +98,7 @@ def patch_document_set(
|
||||
user=user,
|
||||
)
|
||||
except Exception as e:
|
||||
raise HTTPException(status_code=400, detail=str(e))
|
||||
raise OnyxError(OnyxErrorCode.VALIDATION_ERROR, str(e))
|
||||
|
||||
if not DISABLE_VECTOR_DB:
|
||||
client_app.send_task(
|
||||
@@ -116,9 +117,9 @@ def delete_document_set(
|
||||
) -> None:
|
||||
document_set = get_document_set_by_id(db_session, document_set_id)
|
||||
if document_set is None:
|
||||
raise HTTPException(
|
||||
status_code=404,
|
||||
detail=f"Document set {document_set_id} does not exist",
|
||||
raise OnyxError(
|
||||
OnyxErrorCode.NOT_FOUND,
|
||||
f"Document set {document_set_id} does not exist",
|
||||
)
|
||||
|
||||
# check if the user has "edit" access to the document set.
|
||||
@@ -141,7 +142,7 @@ def delete_document_set(
|
||||
user=user,
|
||||
)
|
||||
except Exception as e:
|
||||
raise HTTPException(status_code=400, detail=str(e))
|
||||
raise OnyxError(OnyxErrorCode.VALIDATION_ERROR, str(e))
|
||||
|
||||
if DISABLE_VECTOR_DB:
|
||||
db_session.refresh(document_set)
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
from fastapi import APIRouter
|
||||
from fastapi import Depends
|
||||
from fastapi import HTTPException
|
||||
from sqlalchemy.orm import Session
|
||||
|
||||
from onyx.access.hierarchy_access import get_user_external_group_ids
|
||||
@@ -12,6 +11,8 @@ from onyx.db.engine.sql_engine import get_session
|
||||
from onyx.db.hierarchy import get_accessible_hierarchy_nodes_for_source
|
||||
from onyx.db.models import User
|
||||
from onyx.db.opensearch_migration import get_opensearch_retrieval_state
|
||||
from onyx.error_handling.error_codes import OnyxErrorCode
|
||||
from onyx.error_handling.exceptions import OnyxError
|
||||
from onyx.server.features.hierarchy.constants import DOCUMENT_PAGE_SIZE
|
||||
from onyx.server.features.hierarchy.constants import HIERARCHY_NODE_DOCUMENTS_PATH
|
||||
from onyx.server.features.hierarchy.constants import HIERARCHY_NODES_LIST_PATH
|
||||
@@ -43,14 +44,14 @@ router = APIRouter(prefix=HIERARCHY_NODES_PREFIX)
|
||||
|
||||
def _require_opensearch(db_session: Session) -> None:
|
||||
if not ENABLE_OPENSEARCH_INDEXING_FOR_ONYX:
|
||||
raise HTTPException(
|
||||
status_code=403,
|
||||
detail=OPENSEARCH_NOT_ENABLED_MESSAGE,
|
||||
raise OnyxError(
|
||||
OnyxErrorCode.UNAUTHORIZED,
|
||||
OPENSEARCH_NOT_ENABLED_MESSAGE,
|
||||
)
|
||||
if not get_opensearch_retrieval_state(db_session):
|
||||
raise HTTPException(
|
||||
status_code=403,
|
||||
detail=MIGRATION_STATUS_MESSAGE,
|
||||
raise OnyxError(
|
||||
OnyxErrorCode.UNAUTHORIZED,
|
||||
MIGRATION_STATUS_MESSAGE,
|
||||
)
|
||||
|
||||
|
||||
|
||||
@@ -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.input_prompt import remove_public_input_prompt
|
||||
from onyx.db.input_prompt import update_input_prompt
|
||||
from onyx.db.models import InputPrompt__User
|
||||
from onyx.db.models import User
|
||||
from onyx.error_handling.error_codes import OnyxErrorCode
|
||||
from onyx.error_handling.exceptions import OnyxError
|
||||
from onyx.server.features.input_prompt.models import CreateInputPromptRequest
|
||||
from onyx.server.features.input_prompt.models import InputPromptSnapshot
|
||||
from onyx.server.features.input_prompt.models import UpdateInputPromptRequest
|
||||
@@ -97,7 +98,7 @@ def patch_input_prompt(
|
||||
except ValueError as e:
|
||||
error_msg = "Error occurred while updated input prompt"
|
||||
logger.warn(f"{error_msg}. Stack trace: {e}")
|
||||
raise HTTPException(status_code=404, detail=error_msg)
|
||||
raise OnyxError(OnyxErrorCode.NOT_FOUND, error_msg)
|
||||
|
||||
return InputPromptSnapshot.from_model(updated_input_prompt)
|
||||
|
||||
@@ -117,7 +118,7 @@ def delete_input_prompt(
|
||||
except ValueError as e:
|
||||
error_msg = "Error occurred while deleting input prompt"
|
||||
logger.warn(f"{error_msg}. Stack trace: {e}")
|
||||
raise HTTPException(status_code=404, detail=error_msg)
|
||||
raise OnyxError(OnyxErrorCode.NOT_FOUND, error_msg)
|
||||
|
||||
|
||||
@admin_router.delete("/{input_prompt_id}")
|
||||
@@ -132,7 +133,7 @@ def delete_public_input_prompt(
|
||||
except ValueError as e:
|
||||
error_msg = "Error occurred while deleting input prompt"
|
||||
logger.warn(f"{error_msg}. Stack trace: {e}")
|
||||
raise HTTPException(status_code=404, detail=error_msg)
|
||||
raise OnyxError(OnyxErrorCode.NOT_FOUND, error_msg)
|
||||
|
||||
|
||||
@basic_router.post("/{input_prompt_id}/hide")
|
||||
|
||||
@@ -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_user
|
||||
@@ -9,6 +8,8 @@ from onyx.db.models import User
|
||||
from onyx.db.notification import dismiss_notification
|
||||
from onyx.db.notification import get_notification_by_id
|
||||
from onyx.db.notification import get_notifications
|
||||
from onyx.error_handling.error_codes import OnyxErrorCode
|
||||
from onyx.error_handling.exceptions import OnyxError
|
||||
from onyx.server.features.build.utils import ensure_build_mode_intro_notification
|
||||
from onyx.server.features.release_notes.utils import (
|
||||
ensure_release_notes_fresh_and_notify,
|
||||
@@ -64,10 +65,10 @@ def dismiss_notification_endpoint(
|
||||
try:
|
||||
notification = get_notification_by_id(notification_id, user, db_session)
|
||||
except PermissionError:
|
||||
raise HTTPException(
|
||||
status_code=403, detail="Not authorized to dismiss this notification"
|
||||
raise OnyxError(
|
||||
OnyxErrorCode.UNAUTHORIZED, "Not authorized to dismiss this notification"
|
||||
)
|
||||
except ValueError:
|
||||
raise HTTPException(status_code=404, detail="Notification not found")
|
||||
raise OnyxError(OnyxErrorCode.NOT_FOUND, "Notification not found")
|
||||
|
||||
dismiss_notification(notification, db_session)
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
|
||||
from fastapi import APIRouter
|
||||
from fastapi import Depends
|
||||
from fastapi import HTTPException
|
||||
from sqlalchemy.orm import Session
|
||||
|
||||
from onyx.auth.oauth_token_manager import OAuthTokenManager
|
||||
@@ -20,6 +19,8 @@ from onyx.db.oauth_config import get_oauth_configs
|
||||
from onyx.db.oauth_config import get_tools_by_oauth_config
|
||||
from onyx.db.oauth_config import update_oauth_config
|
||||
from onyx.db.oauth_config import upsert_user_oauth_token
|
||||
from onyx.error_handling.error_codes import OnyxErrorCode
|
||||
from onyx.error_handling.exceptions import OnyxError
|
||||
from onyx.federated_connectors.oauth_utils import generate_oauth_state
|
||||
from onyx.federated_connectors.oauth_utils import verify_oauth_state
|
||||
from onyx.server.features.oauth_config.models import OAuthCallbackResponse
|
||||
@@ -79,7 +80,7 @@ def create_oauth_config_endpoint(
|
||||
)
|
||||
return _oauth_config_to_snapshot(oauth_config, db_session)
|
||||
except ValueError as e:
|
||||
raise HTTPException(status_code=400, detail=str(e))
|
||||
raise OnyxError(OnyxErrorCode.VALIDATION_ERROR, str(e))
|
||||
|
||||
|
||||
@admin_router.get("")
|
||||
@@ -101,8 +102,8 @@ def get_oauth_config_endpoint(
|
||||
"""Retrieve a single OAuth configuration (admin only)."""
|
||||
oauth_config = get_oauth_config(oauth_config_id, db_session)
|
||||
if not oauth_config:
|
||||
raise HTTPException(
|
||||
status_code=404, detail=f"OAuth config with id {oauth_config_id} not found"
|
||||
raise OnyxError(
|
||||
OnyxErrorCode.NOT_FOUND, f"OAuth config with id {oauth_config_id} not found"
|
||||
)
|
||||
return _oauth_config_to_snapshot(oauth_config, db_session)
|
||||
|
||||
@@ -131,7 +132,7 @@ def update_oauth_config_endpoint(
|
||||
)
|
||||
return _oauth_config_to_snapshot(updated_config, db_session)
|
||||
except ValueError as e:
|
||||
raise HTTPException(status_code=404, detail=str(e))
|
||||
raise OnyxError(OnyxErrorCode.NOT_FOUND, str(e))
|
||||
|
||||
|
||||
@admin_router.delete("/{oauth_config_id}")
|
||||
@@ -145,7 +146,7 @@ def delete_oauth_config_endpoint(
|
||||
delete_oauth_config(oauth_config_id, db_session)
|
||||
return {"message": "OAuth configuration deleted successfully"}
|
||||
except ValueError as e:
|
||||
raise HTTPException(status_code=404, detail=str(e))
|
||||
raise OnyxError(OnyxErrorCode.NOT_FOUND, str(e))
|
||||
|
||||
|
||||
"""User endpoints for OAuth flow"""
|
||||
@@ -165,9 +166,9 @@ def initiate_oauth_flow(
|
||||
# Get OAuth config
|
||||
oauth_config = get_oauth_config(request.oauth_config_id, db_session)
|
||||
if not oauth_config:
|
||||
raise HTTPException(
|
||||
status_code=404,
|
||||
detail=f"OAuth config with id {request.oauth_config_id} not found",
|
||||
raise OnyxError(
|
||||
OnyxErrorCode.NOT_FOUND,
|
||||
f"OAuth config with id {request.oauth_config_id} not found",
|
||||
)
|
||||
|
||||
# Generate state parameter and store in Redis
|
||||
@@ -206,8 +207,8 @@ def handle_oauth_callback(
|
||||
|
||||
# Verify the user_id matches
|
||||
if str(user.id) != session.user_id:
|
||||
raise HTTPException(
|
||||
status_code=403, detail="User mismatch in OAuth callback"
|
||||
raise OnyxError(
|
||||
OnyxErrorCode.UNAUTHORIZED, "User mismatch in OAuth callback"
|
||||
)
|
||||
|
||||
# Extract oauth_config_id from session (stored during initiate)
|
||||
@@ -216,9 +217,9 @@ def handle_oauth_callback(
|
||||
# Get OAuth config
|
||||
oauth_config = get_oauth_config(oauth_config_id, db_session)
|
||||
if not oauth_config:
|
||||
raise HTTPException(
|
||||
status_code=404,
|
||||
detail=f"OAuth config with id {oauth_config_id} not found",
|
||||
raise OnyxError(
|
||||
OnyxErrorCode.NOT_FOUND,
|
||||
f"OAuth config with id {oauth_config_id} not found",
|
||||
)
|
||||
|
||||
# Exchange code for token
|
||||
@@ -262,4 +263,4 @@ def revoke_oauth_token(
|
||||
delete_user_oauth_token(oauth_config_id, user.id, db_session)
|
||||
return {"message": "OAuth token revoked successfully"}
|
||||
except ValueError as e:
|
||||
raise HTTPException(status_code=404, detail=str(e))
|
||||
raise OnyxError(OnyxErrorCode.NOT_FOUND, str(e))
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
from fastapi import APIRouter
|
||||
from fastapi import Depends
|
||||
from fastapi import HTTPException
|
||||
from fastapi_users.exceptions import InvalidPasswordException
|
||||
from sqlalchemy.orm import Session
|
||||
|
||||
@@ -11,6 +10,8 @@ from onyx.auth.users import User
|
||||
from onyx.auth.users import UserManager
|
||||
from onyx.db.engine.sql_engine import get_session
|
||||
from onyx.db.users import get_user_by_email
|
||||
from onyx.error_handling.error_codes import OnyxErrorCode
|
||||
from onyx.error_handling.exceptions import OnyxError
|
||||
from onyx.server.features.password.models import ChangePasswordRequest
|
||||
from onyx.server.features.password.models import UserResetRequest
|
||||
from onyx.server.features.password.models import UserResetResponse
|
||||
@@ -34,10 +35,10 @@ async def change_my_password(
|
||||
new_password=form_data.new_password,
|
||||
)
|
||||
except InvalidPasswordException as e:
|
||||
raise HTTPException(status_code=400, detail=str(e.reason))
|
||||
raise OnyxError(OnyxErrorCode.VALIDATION_ERROR, str(e.reason))
|
||||
except Exception as e:
|
||||
raise HTTPException(
|
||||
status_code=500, detail=f"An unexpected error occurred: {str(e)}"
|
||||
raise OnyxError(
|
||||
OnyxErrorCode.INTERNAL_ERROR, f"An unexpected error occurred: {str(e)}"
|
||||
)
|
||||
|
||||
|
||||
@@ -53,7 +54,7 @@ async def admin_reset_user_password(
|
||||
"""
|
||||
user = get_user_by_email(user_reset_request.user_email, db_session)
|
||||
if not user:
|
||||
raise HTTPException(status_code=404, detail="User not found")
|
||||
raise OnyxError(OnyxErrorCode.USER_NOT_FOUND, "User not found")
|
||||
new_password = await user_manager.reset_password_as_admin(user.id)
|
||||
return UserResetResponse(
|
||||
user_id=str(user.id),
|
||||
|
||||
@@ -2,7 +2,6 @@ from uuid import UUID
|
||||
|
||||
from fastapi import APIRouter
|
||||
from fastapi import Depends
|
||||
from fastapi import HTTPException
|
||||
from fastapi import Query
|
||||
from fastapi import UploadFile
|
||||
from pydantic import BaseModel
|
||||
@@ -38,6 +37,8 @@ from onyx.db.persona import update_persona_public_status
|
||||
from onyx.db.persona import update_persona_shared
|
||||
from onyx.db.persona import update_persona_visibility
|
||||
from onyx.db.persona import update_personas_display_priority
|
||||
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.file_store.models import ChatFileType
|
||||
from onyx.server.documents.models import PaginatedReturn
|
||||
@@ -69,9 +70,9 @@ def _validate_user_knowledge_enabled(
|
||||
if persona_upsert_request.user_file_ids or getattr(
|
||||
persona_upsert_request, "user_project_ids", None
|
||||
):
|
||||
raise HTTPException(
|
||||
status_code=400,
|
||||
detail=f"User Knowledge is disabled. Cannot {action} assistant with user files or projects.",
|
||||
raise OnyxError(
|
||||
OnyxErrorCode.VALIDATION_ERROR,
|
||||
f"User Knowledge is disabled. Cannot {action} assistant with user files or projects.",
|
||||
)
|
||||
|
||||
|
||||
@@ -88,28 +89,22 @@ def _validate_vector_db_knowledge(
|
||||
return
|
||||
|
||||
if persona_upsert_request.document_set_ids:
|
||||
raise HTTPException(
|
||||
status_code=400,
|
||||
detail=(
|
||||
"Cannot attach document sets to an assistant when "
|
||||
"the vector database is disabled (DISABLE_VECTOR_DB is set)."
|
||||
),
|
||||
raise OnyxError(
|
||||
OnyxErrorCode.VALIDATION_ERROR,
|
||||
"Cannot attach document sets to an assistant when "
|
||||
"the vector database is disabled (DISABLE_VECTOR_DB is set).",
|
||||
)
|
||||
if persona_upsert_request.hierarchy_node_ids:
|
||||
raise HTTPException(
|
||||
status_code=400,
|
||||
detail=(
|
||||
"Cannot attach hierarchy nodes to an assistant when "
|
||||
"the vector database is disabled (DISABLE_VECTOR_DB is set)."
|
||||
),
|
||||
raise OnyxError(
|
||||
OnyxErrorCode.VALIDATION_ERROR,
|
||||
"Cannot attach hierarchy nodes to an assistant when "
|
||||
"the vector database is disabled (DISABLE_VECTOR_DB is set).",
|
||||
)
|
||||
if persona_upsert_request.document_ids:
|
||||
raise HTTPException(
|
||||
status_code=400,
|
||||
detail=(
|
||||
"Cannot attach documents to an assistant when "
|
||||
"the vector database is disabled (DISABLE_VECTOR_DB is set)."
|
||||
),
|
||||
raise OnyxError(
|
||||
OnyxErrorCode.VALIDATION_ERROR,
|
||||
"Cannot attach documents to an assistant when "
|
||||
"the vector database is disabled (DISABLE_VECTOR_DB is set).",
|
||||
)
|
||||
|
||||
|
||||
@@ -165,7 +160,7 @@ def patch_user_persona_public_status(
|
||||
)
|
||||
except ValueError as e:
|
||||
logger.exception("Failed to update persona public status")
|
||||
raise HTTPException(status_code=403, detail=str(e))
|
||||
raise OnyxError(OnyxErrorCode.UNAUTHORIZED, str(e))
|
||||
|
||||
|
||||
@admin_router.patch("/{persona_id}/featured")
|
||||
@@ -184,7 +179,7 @@ def patch_persona_featured_status(
|
||||
)
|
||||
except ValueError as e:
|
||||
logger.exception("Failed to update persona featured status")
|
||||
raise HTTPException(status_code=403, detail=str(e))
|
||||
raise OnyxError(OnyxErrorCode.UNAUTHORIZED, str(e))
|
||||
|
||||
|
||||
@admin_agents_router.patch("/display-priorities")
|
||||
@@ -202,7 +197,7 @@ def patch_agents_display_priorities(
|
||||
)
|
||||
except ValueError as e:
|
||||
logger.exception("Failed to update agent display priorities.")
|
||||
raise HTTPException(status_code=403, detail=str(e))
|
||||
raise OnyxError(OnyxErrorCode.UNAUTHORIZED, str(e))
|
||||
|
||||
|
||||
@admin_router.get("", tags=PUBLIC_API_TAGS)
|
||||
@@ -372,9 +367,9 @@ def create_label(
|
||||
label_model = create_assistant_label(name=label.name, db_session=db)
|
||||
return PersonaLabelResponse.from_model(label_model)
|
||||
except IntegrityError:
|
||||
raise HTTPException(
|
||||
status_code=400,
|
||||
detail=f"Label with name '{label.name}' already exists. Please choose a different name.",
|
||||
raise OnyxError(
|
||||
OnyxErrorCode.DUPLICATE_RESOURCE,
|
||||
f"Label with name '{label.name}' already exists. Please choose a different name.",
|
||||
)
|
||||
|
||||
|
||||
@@ -428,10 +423,10 @@ def share_persona(
|
||||
)
|
||||
except PermissionError as e:
|
||||
logger.exception("Failed to share persona")
|
||||
raise HTTPException(status_code=403, detail=str(e))
|
||||
raise OnyxError(OnyxErrorCode.UNAUTHORIZED, str(e))
|
||||
except ValueError as e:
|
||||
logger.exception("Failed to share persona")
|
||||
raise HTTPException(status_code=400, detail=str(e))
|
||||
raise OnyxError(OnyxErrorCode.VALIDATION_ERROR, str(e))
|
||||
|
||||
|
||||
@basic_router.delete("/{persona_id}", tags=PUBLIC_API_TAGS)
|
||||
|
||||
@@ -6,7 +6,6 @@ from fastapi import BackgroundTasks
|
||||
from fastapi import Depends
|
||||
from fastapi import File
|
||||
from fastapi import Form
|
||||
from fastapi import HTTPException
|
||||
from fastapi import Response
|
||||
from fastapi import UploadFile
|
||||
from pydantic import BaseModel
|
||||
@@ -29,6 +28,8 @@ from onyx.db.models import UserProject
|
||||
from onyx.db.persona import get_personas_by_ids
|
||||
from onyx.db.projects import get_project_token_count
|
||||
from onyx.db.projects import upload_files_to_user_files_with_indexing
|
||||
from onyx.error_handling.error_codes import OnyxErrorCode
|
||||
from onyx.error_handling.exceptions import OnyxError
|
||||
from onyx.server.features.projects.models import CategorizedFilesSnapshot
|
||||
from onyx.server.features.projects.models import ChatSessionRequest
|
||||
from onyx.server.features.projects.models import TokenCountResponse
|
||||
@@ -115,7 +116,7 @@ def create_project(
|
||||
db_session: Session = Depends(get_session),
|
||||
) -> UserProjectSnapshot:
|
||||
if name == "":
|
||||
raise HTTPException(status_code=400, detail="Project name cannot be empty")
|
||||
raise OnyxError(OnyxErrorCode.VALIDATION_ERROR, "Project name cannot be empty")
|
||||
user_id = user.id
|
||||
project = UserProject(name=name, user_id=user_id)
|
||||
db_session.add(project)
|
||||
@@ -159,9 +160,9 @@ def upload_user_files(
|
||||
|
||||
except Exception as e:
|
||||
logger.exception(f"Error uploading files - {type(e).__name__}: {str(e)}")
|
||||
raise HTTPException(
|
||||
status_code=500,
|
||||
detail="Failed to upload files. Please try again or contact support if the issue persists.",
|
||||
raise OnyxError(
|
||||
OnyxErrorCode.INTERNAL_ERROR,
|
||||
"Failed to upload files. Please try again or contact support if the issue persists.",
|
||||
)
|
||||
|
||||
|
||||
@@ -178,7 +179,7 @@ def get_project(
|
||||
.one_or_none()
|
||||
)
|
||||
if project is None:
|
||||
raise HTTPException(status_code=404, detail="Project not found")
|
||||
raise OnyxError(OnyxErrorCode.NOT_FOUND, "Project not found")
|
||||
return UserProjectSnapshot.from_model(project)
|
||||
|
||||
|
||||
@@ -222,7 +223,7 @@ def unlink_user_file_from_project(
|
||||
.one_or_none()
|
||||
)
|
||||
if project is None:
|
||||
raise HTTPException(status_code=404, detail="Project not found")
|
||||
raise OnyxError(OnyxErrorCode.NOT_FOUND, "Project not found")
|
||||
|
||||
user_file = (
|
||||
db_session.query(UserFile)
|
||||
@@ -230,7 +231,7 @@ def unlink_user_file_from_project(
|
||||
.one_or_none()
|
||||
)
|
||||
if user_file is None:
|
||||
raise HTTPException(status_code=404, detail="File not found")
|
||||
raise OnyxError(OnyxErrorCode.NOT_FOUND, "File not found")
|
||||
|
||||
# Remove the association if it exists
|
||||
if user_file in project.user_files:
|
||||
@@ -268,7 +269,7 @@ def link_user_file_to_project(
|
||||
.one_or_none()
|
||||
)
|
||||
if project is None:
|
||||
raise HTTPException(status_code=404, detail="Project not found")
|
||||
raise OnyxError(OnyxErrorCode.NOT_FOUND, "Project not found")
|
||||
|
||||
user_file = (
|
||||
db_session.query(UserFile)
|
||||
@@ -276,7 +277,7 @@ def link_user_file_to_project(
|
||||
.one_or_none()
|
||||
)
|
||||
if user_file is None:
|
||||
raise HTTPException(status_code=404, detail="File not found")
|
||||
raise OnyxError(OnyxErrorCode.NOT_FOUND, "File not found")
|
||||
|
||||
if user_file not in project.user_files:
|
||||
user_file.needs_project_sync = True
|
||||
@@ -311,7 +312,7 @@ def get_project_instructions(
|
||||
)
|
||||
|
||||
if project is None:
|
||||
raise HTTPException(status_code=404, detail="Project not found")
|
||||
raise OnyxError(OnyxErrorCode.NOT_FOUND, "Project not found")
|
||||
|
||||
return ProjectInstructionsResponse(instructions=project.instructions)
|
||||
|
||||
@@ -340,7 +341,7 @@ def upsert_project_instructions(
|
||||
.one_or_none()
|
||||
)
|
||||
if project is None:
|
||||
raise HTTPException(status_code=404, detail="Project not found")
|
||||
raise OnyxError(OnyxErrorCode.NOT_FOUND, "Project not found")
|
||||
project.instructions = body.instructions
|
||||
|
||||
db_session.commit()
|
||||
@@ -397,7 +398,7 @@ def update_project(
|
||||
.one_or_none()
|
||||
)
|
||||
if project is None:
|
||||
raise HTTPException(status_code=404, detail="Project not found")
|
||||
raise OnyxError(OnyxErrorCode.NOT_FOUND, "Project not found")
|
||||
|
||||
if body.name is not None:
|
||||
project.name = body.name
|
||||
@@ -422,7 +423,7 @@ def delete_project(
|
||||
.one_or_none()
|
||||
)
|
||||
if project is None:
|
||||
raise HTTPException(status_code=404, detail="Project not found")
|
||||
raise OnyxError(OnyxErrorCode.NOT_FOUND, "Project not found")
|
||||
|
||||
# Unlink chat sessions from this project
|
||||
for chat in project.chat_sessions:
|
||||
@@ -455,7 +456,7 @@ def delete_user_file(
|
||||
.one_or_none()
|
||||
)
|
||||
if user_file is None:
|
||||
raise HTTPException(status_code=404, detail="File not found")
|
||||
raise OnyxError(OnyxErrorCode.NOT_FOUND, "File not found")
|
||||
|
||||
# Check associations with projects and assistants (personas)
|
||||
project_names = [project.name for project in user_file.projects]
|
||||
@@ -515,7 +516,7 @@ def get_user_file(
|
||||
.one_or_none()
|
||||
)
|
||||
if user_file is None:
|
||||
raise HTTPException(status_code=404, detail="File not found")
|
||||
raise OnyxError(OnyxErrorCode.NOT_FOUND, "File not found")
|
||||
return UserFileSnapshot.from_model(user_file)
|
||||
|
||||
|
||||
@@ -564,7 +565,7 @@ def move_chat_session(
|
||||
.one_or_none()
|
||||
)
|
||||
if chat_session is None:
|
||||
raise HTTPException(status_code=404, detail="Chat session not found")
|
||||
raise OnyxError(OnyxErrorCode.SESSION_NOT_FOUND, "Chat session not found")
|
||||
chat_session.project_id = project_id
|
||||
db_session.commit()
|
||||
return Response(status_code=204)
|
||||
@@ -583,7 +584,7 @@ def remove_chat_session(
|
||||
.one_or_none()
|
||||
)
|
||||
if chat_session is None:
|
||||
raise HTTPException(status_code=404, detail="Chat session not found")
|
||||
raise OnyxError(OnyxErrorCode.SESSION_NOT_FOUND, "Chat session not found")
|
||||
chat_session.project_id = None
|
||||
db_session.commit()
|
||||
return Response(status_code=204)
|
||||
@@ -606,7 +607,7 @@ def get_chat_session_project_token_count(
|
||||
.one_or_none()
|
||||
)
|
||||
if chat_session is None:
|
||||
raise HTTPException(status_code=404, detail="Chat session not found")
|
||||
raise OnyxError(OnyxErrorCode.SESSION_NOT_FOUND, "Chat session not found")
|
||||
|
||||
total_tokens = get_project_token_count(
|
||||
project_id=chat_session.project_id,
|
||||
@@ -636,7 +637,7 @@ def get_chat_session_project_files(
|
||||
.one_or_none()
|
||||
)
|
||||
if chat_session is None:
|
||||
raise HTTPException(status_code=404, detail="Chat session not found")
|
||||
raise OnyxError(OnyxErrorCode.SESSION_NOT_FOUND, "Chat session not found")
|
||||
|
||||
if chat_session.project_id is None:
|
||||
return []
|
||||
@@ -671,7 +672,7 @@ def get_project_total_token_count(
|
||||
.one_or_none()
|
||||
)
|
||||
if project is None:
|
||||
raise HTTPException(status_code=404, detail="Project not found")
|
||||
raise OnyxError(OnyxErrorCode.NOT_FOUND, "Project not found")
|
||||
|
||||
total_tokens = get_project_token_count(
|
||||
project_id=project_id,
|
||||
|
||||
@@ -2,7 +2,6 @@ from typing import Any
|
||||
|
||||
from fastapi import APIRouter
|
||||
from fastapi import Depends
|
||||
from fastapi import HTTPException
|
||||
from pydantic import BaseModel
|
||||
from sqlalchemy.orm import Session
|
||||
|
||||
@@ -19,6 +18,8 @@ from onyx.db.tools import get_tool_by_id
|
||||
from onyx.db.tools import get_tools
|
||||
from onyx.db.tools import get_tools_by_ids
|
||||
from onyx.db.tools import update_tool
|
||||
from onyx.error_handling.error_codes import OnyxErrorCode
|
||||
from onyx.error_handling.exceptions import OnyxError
|
||||
from onyx.server.features.tool.models import CustomToolCreate
|
||||
from onyx.server.features.tool.models import CustomToolUpdate
|
||||
from onyx.server.features.tool.models import ToolSnapshot
|
||||
@@ -40,16 +41,16 @@ def _validate_tool_definition(definition: dict[str, Any]) -> None:
|
||||
try:
|
||||
validate_openapi_schema(definition)
|
||||
except Exception as e:
|
||||
raise HTTPException(status_code=400, detail=str(e))
|
||||
raise OnyxError(OnyxErrorCode.VALIDATION_ERROR, str(e))
|
||||
|
||||
|
||||
def _validate_auth_settings(tool_data: CustomToolCreate | CustomToolUpdate) -> None:
|
||||
if tool_data.passthrough_auth and tool_data.custom_headers:
|
||||
for header in tool_data.custom_headers:
|
||||
if header.key.lower() == "authorization":
|
||||
raise HTTPException(
|
||||
status_code=400,
|
||||
detail="Cannot use passthrough auth with custom authorization headers",
|
||||
raise OnyxError(
|
||||
OnyxErrorCode.VALIDATION_ERROR,
|
||||
"Cannot use passthrough auth with custom authorization headers",
|
||||
)
|
||||
|
||||
|
||||
@@ -58,12 +59,12 @@ def _get_editable_custom_tool(tool_id: int, db_session: Session, user: User) ->
|
||||
try:
|
||||
tool = get_tool_by_id(tool_id, db_session)
|
||||
except ValueError as e:
|
||||
raise HTTPException(status_code=404, detail=str(e))
|
||||
raise OnyxError(OnyxErrorCode.NOT_FOUND, str(e))
|
||||
|
||||
if tool.in_code_tool_id is not None:
|
||||
raise HTTPException(
|
||||
status_code=400,
|
||||
detail="Built-in tools cannot be modified through this endpoint.",
|
||||
raise OnyxError(
|
||||
OnyxErrorCode.VALIDATION_ERROR,
|
||||
"Built-in tools cannot be modified through this endpoint.",
|
||||
)
|
||||
|
||||
# Admins can always make changes; non-admins must own the tool.
|
||||
@@ -71,9 +72,9 @@ def _get_editable_custom_tool(tool_id: int, db_session: Session, user: User) ->
|
||||
return tool
|
||||
|
||||
if tool.user_id is None or tool.user_id != user.id:
|
||||
raise HTTPException(
|
||||
status_code=403,
|
||||
detail="You can only modify actions that you created.",
|
||||
raise OnyxError(
|
||||
OnyxErrorCode.UNAUTHORIZED,
|
||||
"You can only modify actions that you created.",
|
||||
)
|
||||
|
||||
return tool
|
||||
@@ -137,10 +138,10 @@ def delete_custom_tool(
|
||||
try:
|
||||
delete_tool__no_commit(tool_id, db_session)
|
||||
except ValueError as e:
|
||||
raise HTTPException(status_code=404, detail=str(e))
|
||||
raise OnyxError(OnyxErrorCode.NOT_FOUND, str(e))
|
||||
except Exception as e:
|
||||
# handles case where tool is still used by an Assistant
|
||||
raise HTTPException(status_code=400, detail=str(e))
|
||||
raise OnyxError(OnyxErrorCode.VALIDATION_ERROR, str(e))
|
||||
db_session.commit()
|
||||
|
||||
|
||||
@@ -166,7 +167,7 @@ def update_tools_status(
|
||||
bulk updates.
|
||||
"""
|
||||
if not update_data.tool_ids:
|
||||
raise HTTPException(status_code=400, detail="No tool IDs provided")
|
||||
raise OnyxError(OnyxErrorCode.VALIDATION_ERROR, "No tool IDs provided")
|
||||
|
||||
tools = get_tools_by_ids(update_data.tool_ids, db_session)
|
||||
tools_by_id = {tool.id: tool for tool in tools}
|
||||
@@ -183,8 +184,8 @@ def update_tools_status(
|
||||
missing_tools.append(tool_id)
|
||||
|
||||
if missing_tools:
|
||||
raise HTTPException(
|
||||
status_code=404, detail=f"Tools with IDs {missing_tools} not found"
|
||||
raise OnyxError(
|
||||
OnyxErrorCode.NOT_FOUND, f"Tools with IDs {missing_tools} not found"
|
||||
)
|
||||
|
||||
db_session.commit()
|
||||
@@ -242,7 +243,7 @@ def get_custom_tool(
|
||||
try:
|
||||
tool = get_tool_by_id(tool_id, db_session)
|
||||
except ValueError as e:
|
||||
raise HTTPException(status_code=404, detail=str(e))
|
||||
raise OnyxError(OnyxErrorCode.NOT_FOUND, str(e))
|
||||
return ToolSnapshot.from_model(tool)
|
||||
|
||||
|
||||
|
||||
@@ -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_user
|
||||
@@ -9,6 +8,8 @@ from onyx.db.engine.sql_engine import get_session
|
||||
from onyx.db.models import User
|
||||
from onyx.db.web_search import fetch_active_web_content_provider
|
||||
from onyx.db.web_search import fetch_active_web_search_provider
|
||||
from onyx.error_handling.error_codes import OnyxErrorCode
|
||||
from onyx.error_handling.exceptions import OnyxError
|
||||
from onyx.server.features.web_search.models import OpenUrlsToolRequest
|
||||
from onyx.server.features.web_search.models import OpenUrlsToolResponse
|
||||
from onyx.server.features.web_search.models import WebSearchToolRequest
|
||||
@@ -61,9 +62,9 @@ def _get_active_search_provider(
|
||||
) -> tuple[WebSearchProviderView, WebSearchProvider]:
|
||||
provider_model = fetch_active_web_search_provider(db_session)
|
||||
if provider_model is None:
|
||||
raise HTTPException(
|
||||
status_code=400,
|
||||
detail="No web search provider configured.",
|
||||
raise OnyxError(
|
||||
OnyxErrorCode.VALIDATION_ERROR,
|
||||
"No web search provider configured.",
|
||||
)
|
||||
|
||||
provider_view = WebSearchProviderView(
|
||||
@@ -76,9 +77,9 @@ def _get_active_search_provider(
|
||||
)
|
||||
|
||||
if provider_model.api_key is None:
|
||||
raise HTTPException(
|
||||
status_code=400,
|
||||
detail="Web search provider requires an API key.",
|
||||
raise OnyxError(
|
||||
OnyxErrorCode.VALIDATION_ERROR,
|
||||
"Web search provider requires an API key.",
|
||||
)
|
||||
|
||||
try:
|
||||
@@ -88,7 +89,7 @@ def _get_active_search_provider(
|
||||
config=provider_model.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
|
||||
|
||||
return provider_view, provider
|
||||
|
||||
@@ -110,9 +111,9 @@ def _get_active_content_provider(
|
||||
|
||||
if provider_model.api_key is None:
|
||||
# TODO - this is not a great error, in fact, this key should not be nullable.
|
||||
raise HTTPException(
|
||||
status_code=400,
|
||||
detail="Web content provider requires an API key.",
|
||||
raise OnyxError(
|
||||
OnyxErrorCode.VALIDATION_ERROR,
|
||||
"Web content provider requires an API key.",
|
||||
)
|
||||
|
||||
try:
|
||||
@@ -125,12 +126,12 @@ def _get_active_content_provider(
|
||||
config=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 initialize the configured web content provider.",
|
||||
raise OnyxError(
|
||||
OnyxErrorCode.VALIDATION_ERROR,
|
||||
"Unable to initialize the configured web content provider.",
|
||||
)
|
||||
|
||||
provider_view = WebContentProviderView(
|
||||
@@ -154,12 +155,13 @@ def _run_web_search(
|
||||
for query in request.queries:
|
||||
try:
|
||||
search_results = provider.search(query)
|
||||
except HTTPException:
|
||||
except OnyxError:
|
||||
raise
|
||||
except Exception as exc:
|
||||
logger.exception("Web search provider failed for query '%s'", query)
|
||||
raise HTTPException(
|
||||
status_code=502, detail="Web search provider failed to execute query."
|
||||
raise OnyxError(
|
||||
OnyxErrorCode.BAD_GATEWAY,
|
||||
"Web search provider failed to execute query.",
|
||||
) from exc
|
||||
|
||||
filtered_results = filter_web_search_results_with_no_title_or_snippet(
|
||||
@@ -192,12 +194,12 @@ def _open_urls(
|
||||
docs = filter_web_contents_with_no_title_or_content(
|
||||
list(provider.contents(urls))
|
||||
)
|
||||
except HTTPException:
|
||||
except OnyxError:
|
||||
raise
|
||||
except Exception as exc:
|
||||
logger.exception("Web content provider failed to fetch URLs")
|
||||
raise HTTPException(
|
||||
status_code=502, detail="Web content provider failed to fetch URLs."
|
||||
raise OnyxError(
|
||||
OnyxErrorCode.BAD_GATEWAY, "Web content provider failed to fetch URLs."
|
||||
) from exc
|
||||
|
||||
results: list[LlmOpenUrlResult] = []
|
||||
|
||||
Reference in New Issue
Block a user