87 lines
2.6 KiB
Python
87 lines
2.6 KiB
Python
import json
|
|
import re
|
|
import uuid
|
|
from datetime import datetime
|
|
from random import randint
|
|
|
|
import pydantic
|
|
from fastapi import APIRouter, Depends, HTTPException
|
|
from fastapi.responses import JSONResponse
|
|
from pydantic import ValidationError
|
|
|
|
from classquiz.auth import get_current_user, get_current_user_optional
|
|
from classquiz.config import redis, settings, storage, meilisearch
|
|
from uuid import UUID
|
|
from typing import Optional, List
|
|
from classquiz.db.models import Quiz, QuizInput, User, PlayGame
|
|
from classquiz.kahoot_importer.import_quiz import import_quiz
|
|
|
|
settings = settings()
|
|
|
|
router = APIRouter()
|
|
|
|
|
|
class Hit(pydantic.BaseModel):
|
|
id: UUID
|
|
title: str
|
|
description: str
|
|
user: str
|
|
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
|
|
|
|
|
|
@router.post("/", response_model=SearchResponse)
|
|
async def search(data: SearchData):
|
|
index = meilisearch.get_index(settings.meilisearch_index)
|
|
query = index.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
|
|
})
|
|
return SearchResponse(**query)
|
|
|
|
|
|
@router.get("/", response_model=SearchResponse)
|
|
async def search_get(q: str, offset: int = 0, limit: int = 20, filter: str | None = None,
|
|
cropLength: int = 200, matches: bool = False, attributesToHighlight: Optional[str] = "*"):
|
|
index = meilisearch.get_index(settings.meilisearch_index)
|
|
query = index.search(q, {
|
|
"offset": offset,
|
|
"limit": limit,
|
|
"filter": filter,
|
|
"cropLength": cropLength,
|
|
"matches": matches,
|
|
"attributesToHighlight": [attributesToHighlight]
|
|
})
|
|
return SearchResponse(**query)
|