AlleksDev's picture
Fix: Custom Feed
5c793cc unverified
Raw
History Blame Contribute Delete
2.24 kB
from dataclasses import dataclass, field
from typing import Any
from app.modules.posts.domain.models import PostCandidate
from app.modules.posts.domain.ports.cache import Cache
from app.modules.posts.domain.ports.embedding_provider import EmbeddingProvider
from app.modules.posts.domain.ports.post_repository import PostVectorRepository
from app.modules.posts.domain.ports.ranker import PostRanker
from app.modules.posts.domain.ports.text_preprocessor import TextPreprocessor
@dataclass(frozen=True)
class RecommendPostsResult:
query: str
posts: list[PostCandidate]
metadata: dict[str, Any] = field(default_factory=dict)
class RecommendPostsUseCase:
def __init__(
self,
embedding_provider: EmbeddingProvider,
text_preprocessor: TextPreprocessor,
post_repository: PostVectorRepository,
ranker: PostRanker,
cache: Cache | None = None,
) -> None:
self._embedding_provider = embedding_provider
self._text_preprocessor = text_preprocessor
self._post_repository = post_repository
self._ranker = ranker
self._cache = cache
async def execute(
self,
query: str,
city: str | None = None,
limit: int = 10,
) -> RecommendPostsResult:
normalized_query = self._text_preprocessor.prepare(query)
cache_key = f"posts:{normalized_query}:{city}:{limit}"
if self._cache:
cached = self._cache.get(cache_key)
if cached is not None:
return cached
query_embedding = self._embedding_provider.embed_text(normalized_query)
candidates = await self._post_repository.search(
embedding=query_embedding,
city=city,
limit=max(limit * 3, limit),
)
ranked_posts = self._ranker.rank(candidates, limit)
result = RecommendPostsResult(
query=query,
posts=ranked_posts,
metadata={
"strategy": "semantic_search_plus_ranking",
"used_llm": False,
"computed_clusters_during_request": False,
},
)
if self._cache:
self._cache.set(cache_key, result)
return result