Files
blog.pyaqa.ru/app/application/use_cases/list_posts.py
Sergey Vanyushkin ca4e8877a5 docs: add AI code generation requirements and comprehensive Google-style docstrings
- Add AI code generation requirements to AGENTS.md
- Add module-level docstrings to all 46 Python modules
- Add detailed Google-style docstrings to all classes and functions
- Remove all inline comments following self-documenting code principle
- Include Args, Returns, Raises sections in function docstrings
- Add Attributes and Examples sections to class docstrings
2026-05-02 13:15:21 +03:00

145 lines
4.3 KiB
Python

"""List posts use case.
This module implements the use case for listing blog posts.
Provides multiple query methods including filtering by author, tag, and search.
"""
from app.application.dtos.post import PostResponseDTO
from app.application.interfaces import TransactionManager
from app.domain.entities import Post
from app.domain.repositories import PostRepository
class ListPostsUseCase:
"""Use case for listing blog posts with filtering.
Provides various methods to query posts with different criteria
including pagination support for large result sets.
Attributes:
_post_repo: Repository for post data access.
_tx_manager: Transaction manager for transaction control.
Example:
>>> use_case = ListPostsUseCase(post_repo, tx_manager)
>>> posts = await use_case.published_posts(limit=10, offset=0)
"""
def __init__(
self,
post_repo: PostRepository,
tx_manager: TransactionManager,
) -> None:
"""Initialize use case with dependencies.
Args:
post_repo: Repository for post operations.
tx_manager: Transaction manager instance.
"""
self._post_repo = post_repo
self._tx_manager = tx_manager
async def all_posts(self) -> list[PostResponseDTO]:
"""Get all posts.
Returns:
List of PostResponseDTO for all posts.
"""
posts = await self._post_repo.get_all()
return [self._map_to_dto(post) for post in posts]
async def published_posts(
self,
limit: int | None = None,
offset: int | None = None,
) -> list[PostResponseDTO]:
"""Get all published posts.
Args:
limit: Maximum number of posts to return.
offset: Number of posts to skip.
Returns:
List of PostResponseDTO for published posts.
"""
posts = await self._post_repo.get_published(limit=limit, offset=offset)
return [self._map_to_dto(post) for post in posts]
async def by_author(
self,
author_id: str,
limit: int | None = None,
offset: int | None = None,
) -> list[PostResponseDTO]:
"""Get posts by author.
Args:
author_id: Identifier of the author.
limit: Maximum number of posts to return.
offset: Number of posts to skip.
Returns:
List of PostResponseDTO for posts by the author.
"""
posts = await self._post_repo.get_by_author(author_id, limit=limit, offset=offset)
return [self._map_to_dto(post) for post in posts]
async def by_tag(
self,
tag: str,
limit: int | None = None,
offset: int | None = None,
) -> list[PostResponseDTO]:
"""Get posts by tag.
Args:
tag: Tag to filter by.
limit: Maximum number of posts to return.
offset: Number of posts to skip.
Returns:
List of PostResponseDTO for posts with the tag.
"""
posts = await self._post_repo.get_by_tag(tag, limit=limit, offset=offset)
return [self._map_to_dto(post) for post in posts]
async def search(
self,
query: str,
limit: int | None = None,
offset: int | None = None,
) -> list[PostResponseDTO]:
"""Search posts.
Args:
query: Search query string.
limit: Maximum number of posts to return.
offset: Number of posts to skip.
Returns:
List of PostResponseDTO for matching posts.
"""
posts = await self._post_repo.search(query, limit=limit, offset=offset)
return [self._map_to_dto(post) for post in posts]
def _map_to_dto(self, post: Post) -> PostResponseDTO:
"""Map domain entity to response DTO.
Args:
post: Domain post entity.
Returns:
PostResponseDTO with all post attributes.
"""
return PostResponseDTO(
id=post.id,
title=post.title.value,
content=post.content.value,
slug=post.slug.value,
author_id=post.author_id,
published=post.published,
tags=post.tags.copy(),
created_at=post.created_at,
updated_at=post.updated_at,
)