year_fallback
¶
Year fallback logic extracted from YearRetriever.
This module handles the decision logic for when to apply, skip, or preserve year values based on confidence levels and existing data.
YearFallbackHandler
¶
YearFallbackHandler(
*,
console_logger,
pending_verification,
fallback_enabled,
absurd_year_threshold,
year_difference_threshold,
trust_api_score_threshold=DEFAULT_TRUST_API_SCORE_THRESHOLD,
min_confidence_for_new_year=DEFAULT_MIN_CONFIDENCE_FOR_NEW_YEAR,
api_orchestrator=None
)
Handles fallback logic for year decisions.
Decision Tree: 1. IF is_definitive=True → APPLY proposed year (high confidence from API) 2. IF proposed_year < absurd_threshold AND no existing year → MARK and SKIP 3. IF existing year is EMPTY → APPLY proposed year (nothing to preserve) 4. IF is_special_album_type → MARK and PROPAGATE existing year to all tracks 5. IF |proposed - existing| > THRESHOLD → MARK and PROPAGATE existing year to all tracks 6. ELSE → APPLY proposed year
Key principle: When we trust existing year over proposed year, we PROPAGATE the existing year to ALL tracks (including empty ones), not just preserve it.
Initialize the year fallback handler.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
console_logger
|
Logger
|
Logger for console output |
required |
pending_verification
|
PendingVerificationServiceProtocol
|
Service for marking albums for verification |
required |
fallback_enabled
|
bool
|
Whether fallback logic is enabled |
required |
absurd_year_threshold
|
int
|
Years below this are considered absurd |
required |
year_difference_threshold
|
int
|
Max allowed year difference before dramatic change |
required |
trust_api_score_threshold
|
int
|
Trust API if confidence >= this value |
DEFAULT_TRUST_API_SCORE_THRESHOLD
|
min_confidence_for_new_year
|
int
|
Minimum confidence to apply year when no existing year |
DEFAULT_MIN_CONFIDENCE_FOR_NEW_YEAR
|
api_orchestrator
|
ExternalApiServiceProtocol | None
|
API orchestrator for artist data lookups (optional) |
None
|
Source code in src/core/tracks/year_fallback.py
apply_year_fallback
async
¶
apply_year_fallback(
proposed_year,
album_tracks,
is_definitive,
confidence_score,
artist,
album,
year_scores=None,
release_year=None,
)
Apply fallback logic for year decisions.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
proposed_year
|
str
|
Year from API |
required |
album_tracks
|
list[TrackDict]
|
List of tracks in the album |
required |
is_definitive
|
bool
|
Whether API is confident in the year |
required |
confidence_score
|
int
|
API confidence score (0-100) |
required |
artist
|
str
|
Artist name |
required |
album
|
str
|
Album name |
required |
year_scores
|
dict[str, int] | None
|
Mapping of year to max score from API results (Issue #93) |
None
|
release_year
|
str | None
|
Original release year from Apple Music (read-only, more authoritative) |
None
|
Returns:
| Type | Description |
|---|---|
str | None
|
Year to apply (proposed or existing), or None to skip update |
Source code in src/core/tracks/year_fallback.py
89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 | |
get_existing_year_from_tracks
staticmethod
¶
Extract the most common existing year from tracks.
Uses Counter to find the most frequently occurring year among tracks.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
tracks
|
list[TrackDict]
|
List of tracks to analyze |
required |
Returns:
| Type | Description |
|---|---|
str | None
|
Most common year string, or None if no valid years found |
Source code in src/core/tracks/year_fallback.py
is_year_change_dramatic
¶
Check if year change exceeds the threshold.
A dramatic change (e.g., 2018→1998) suggests the API returned a reissue/compilation year rather than the original.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
existing
|
str
|
Current year value |
required |
proposed
|
str
|
Proposed new year value |
required |
Returns:
| Type | Description |
|---|---|
bool
|
True if difference exceeds year_difference_threshold |