mirror of
https://github.com/danswer-ai/danswer.git
synced 2025-05-03 16:30:21 +02:00
99 lines
2.9 KiB
Python
99 lines
2.9 KiB
Python
import re
|
|
from typing import Any
|
|
|
|
from pydantic import BaseModel
|
|
from pydantic import field_validator
|
|
from pydantic import model_validator
|
|
|
|
from onyx.db.models import StandardAnswer as StandardAnswerModel
|
|
from onyx.db.models import StandardAnswerCategory as StandardAnswerCategoryModel
|
|
|
|
|
|
class StandardAnswerCategoryCreationRequest(BaseModel):
|
|
name: str
|
|
|
|
|
|
class StandardAnswerCategory(BaseModel):
|
|
id: int
|
|
name: str
|
|
|
|
@classmethod
|
|
def from_model(
|
|
cls, standard_answer_category: StandardAnswerCategoryModel
|
|
) -> "StandardAnswerCategory":
|
|
return cls(
|
|
id=standard_answer_category.id,
|
|
name=standard_answer_category.name,
|
|
)
|
|
|
|
|
|
class StandardAnswer(BaseModel):
|
|
id: int
|
|
keyword: str
|
|
answer: str
|
|
categories: list[StandardAnswerCategory]
|
|
match_regex: bool
|
|
match_any_keywords: bool
|
|
|
|
@classmethod
|
|
def from_model(cls, standard_answer_model: StandardAnswerModel) -> "StandardAnswer":
|
|
return cls(
|
|
id=standard_answer_model.id,
|
|
keyword=standard_answer_model.keyword,
|
|
answer=standard_answer_model.answer,
|
|
match_regex=standard_answer_model.match_regex,
|
|
match_any_keywords=standard_answer_model.match_any_keywords,
|
|
categories=[
|
|
StandardAnswerCategory.from_model(standard_answer_category_model)
|
|
for standard_answer_category_model in standard_answer_model.categories
|
|
],
|
|
)
|
|
|
|
|
|
class StandardAnswerCreationRequest(BaseModel):
|
|
keyword: str
|
|
answer: str
|
|
categories: list[int]
|
|
match_regex: bool
|
|
match_any_keywords: bool
|
|
|
|
@field_validator("categories", mode="before")
|
|
@classmethod
|
|
def validate_categories(cls, value: list[int]) -> list[int]:
|
|
if len(value) < 1:
|
|
raise ValueError(
|
|
"At least one category must be attached to a standard answer"
|
|
)
|
|
return value
|
|
|
|
@model_validator(mode="after")
|
|
def validate_only_match_any_if_not_regex(self) -> Any:
|
|
if self.match_regex and self.match_any_keywords:
|
|
raise ValueError(
|
|
"Can only match any keywords in keyword mode, not regex mode"
|
|
)
|
|
|
|
return self
|
|
|
|
@model_validator(mode="after")
|
|
def validate_keyword_if_regex(self) -> Any:
|
|
if not self.match_regex:
|
|
# no validation for keywords
|
|
return self
|
|
|
|
try:
|
|
re.compile(self.keyword)
|
|
return self
|
|
except re.error as err:
|
|
if isinstance(err.pattern, bytes):
|
|
raise ValueError(
|
|
f'invalid regex pattern r"{err.pattern.decode()}" in `keyword`: {err.msg}'
|
|
)
|
|
else:
|
|
pattern = f'r"{err.pattern}"' if err.pattern is not None else ""
|
|
raise ValueError(
|
|
" ".join(
|
|
["invalid regex pattern", pattern, f"in `keyword`: {err.msg}"]
|
|
)
|
|
)
|