Enhance recitation models and services#801
Conversation
- Introduced `first_segment` field in `RecitationDTO` to include the first segment of each recitation. - Added `get_recitations_with_first_segments` function to retrieve and populate the first segments for a list of recitations. - Updated `get_list_of_recitations_service` to utilize the new function for returning recitations with their first segments. - Implemented `get_first_segment_ids_by_text_ids` utility to extract first segment IDs from the table of contents. - Added tests for the new functionality in `test_recitations_services.py` to ensure correct behavior.
Confidence Score: 4/5Safe to merge; the new batched fetch path is functionally correct and early-return guards handle edge cases cleanly. The logic for fetching and mapping first segments is sound — TOC lookup, first-segment extraction, and content fetch all work in batch and fall back gracefully to null when data is missing. The two findings are style-level: duplicate import blocks left over from reorganising the imports, and a positional tuple index that works today but would silently break if the tuple contract changes. Neither affects runtime behaviour. pecha_api/recitations/recitations_services.py — duplicate imports and the tuple-index access are both in the new get_recitations_with_first_segments function. Reviews (1): Last reviewed commit: "Enhance recitation models and services" | Re-trigger Greptile |
| @@ -26,7 +28,6 @@ | |||
| RecitationDetailsResponse, | |||
| Segment, | |||
| RecitationSegment, | |||
| RecitationsResponse | |||
| ) | |||
There was a problem hiding this comment.
RecitationDTO, RecitationsResponse, and Segment are already imported on line 7. The second import block then re-imports RecitationDTO and Segment (it dropped RecitationsResponse in this PR, but the first-block import still covers it). The duplicates shadow each other harmlessly in CPython, but they make it hard to track the canonical import source and cause confusion when renaming or reorganising models. The top-level import and the extended block should be merged into a single statement.
| from pecha_api.recitations.recitations_response_models import ( | |
| RecitationDTO, | |
| RecitationsResponse, | |
| RecitationDetailsRequest, | |
| RecitationDetailsResponse, | |
| Segment, | |
| RecitationSegment, | |
| ) | |
| from pecha_api.texts.texts_repository import get_all_texts_by_collection, get_contents_by_text_ids, get_contents_by_id, get_all_texts_by_group_id | |
| from pecha_api.texts.segments.segments_repository import get_segment_contents_by_ids | |
| from pecha_api.texts.texts_toc_utils import get_first_segment_ids_by_text_ids | |
| from pecha_api.texts.texts_service import get_root_text_by_collection_id | |
| from fastapi import HTTPException | |
| from starlette import status | |
| from uuid import UUID | |
| from pecha_api.error_contants import ErrorConstants | |
| from pecha_api.texts.texts_utils import TextUtils | |
| from pecha_api.texts.texts_response_models import TextDTO, TableOfContent | |
| from pecha_api.texts.segments.segments_service import get_segment_by_id, get_related_mapped_segments, get_segment_details_by_id, get_related_mapped_segments_batch, get_segments_details_by_ids | |
| from pecha_api.texts.segments.segments_utils import SegmentUtils | |
| from pecha_api.texts.segments.segments_response_models import SegmentTranslation, SegmentTransliteration, SegmentAdaptation, SegmentRecitation, SegmentDTO |
Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!
| content_data = segment_contents.get(segment_id) | ||
| if content_data: | ||
| first_segments_by_text_id[text_id] = Segment( | ||
| id=UUID(segment_id), | ||
| content=content_data[1], | ||
| ) |
There was a problem hiding this comment.
content_data[1] relies on undocumented positional knowledge of the tuple returned by get_segment_contents_by_ids (typed as Dict[str, tuple[str, str]]). If the tuple structure ever changes, this silently extracts the wrong value with no type-system or runtime warning. Destructuring with a named variable makes the intent explicit.
| content_data = segment_contents.get(segment_id) | |
| if content_data: | |
| first_segments_by_text_id[text_id] = Segment( | |
| id=UUID(segment_id), | |
| content=content_data[1], | |
| ) | |
| content_data = segment_contents.get(segment_id) | |
| if content_data: | |
| _, segment_content = content_data | |
| first_segments_by_text_id[text_id] = Segment( | |
| id=UUID(segment_id), | |
| content=segment_content, | |
| ) |
|



first_segmentfield inRecitationDTOto include the first segment of each recitation.get_recitations_with_first_segmentsfunction to retrieve and populate the first segments for a list of recitations.get_list_of_recitations_serviceto utilize the new function for returning recitations with their first segments.get_first_segment_ids_by_text_idsutility to extract first segment IDs from the table of contents.test_recitations_services.pyto ensure correct behavior.