Files
classquiz-ai/classquiz/routers/search.py
T
2022-07-15 18:50:45 +02:00

105 lines
3.0 KiB
Python

# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at https://mozilla.org/MPL/2.0/.
import pydantic
from fastapi import APIRouter
from classquiz.config import settings, meilisearch
from uuid import UUID
from typing import Optional, List, Any
from meilisearch.errors import MeiliSearchApiError
from classquiz.helpers import meilisearch_init
settings = settings()
router = APIRouter()
class Hit(pydantic.BaseModel):
id: UUID
title: str
description: str
user: str
imported_from_kahoot: Optional[bool]
formatted: Optional["Hit"] = pydantic.Field(None, alias="_formatted")
class SearchResponse(pydantic.BaseModel):
hits: List[Hit] | list[None]
# nbHits: int
# exhaustiveNbHits: bool
query: str
limit: int
offset: int
processingTimeMs: int
class SearchData(pydantic.BaseModel):
q: str
offset: Optional[int] = 0
limit: Optional[int] = 20
filter: Optional[str] = None
facetsDistribution: Optional[list[str]] = None
attributesToRetrieve: Optional[list[str]] = ["*"]
attributesToCrop: Optional[list[str]] = None
cropLength: Optional[int] = 200
attributesToHighlight: Optional[list[str]] = None
# matches: Optional[bool] = False
sort: Optional[list[str]] = None
async def _perform_search(query: str, params: dict) -> dict[str, Any]:
try:
index = meilisearch.get_index(settings.meilisearch_index)
return index.search(query, params)
except MeiliSearchApiError:
await meilisearch_init()
index = meilisearch.get_index(settings.meilisearch_index)
return index.search(query, params)
@router.post("/", response_model=SearchResponse)
async def search(data: SearchData):
query = await _perform_search(
data.q,
{
"offset": data.offset,
"limit": data.limit,
"filter": data.filter,
"cropLength": data.cropLength,
# "matches": data.matches,
# "facetsDistribution": data.facetsDistribution,
"attributesToRetrieve": data.attributesToRetrieve,
"attributesToCrop": data.attributesToCrop,
"sort": data.sort,
"attributesToHighlight": data.attributesToHighlight,
},
)
print(query)
return SearchResponse(**query)
@router.get("/", response_model=SearchResponse)
async def search_get(
q: str,
offset: int = 0,
limit: int = 20,
filter: str | None = None, # skipcq: PYL-W0622
cropLength: int = 200,
# matches: bool = False,
attributesToHighlight: Optional[str] = "*",
):
query = await _perform_search(
q,
{
"offset": offset,
"limit": limit,
"filter": filter, # skipcq: PYL-W0622
"cropLength": cropLength,
# "matches": matches,
"attributesToHighlight": [attributesToHighlight],
},
)
return SearchResponse(**query)