types
¶
Type definitions for the utils layer.
This module provides type imports that utils modules can use without depending on the services layer, maintaining clean architecture boundaries.
CachedApiResult
¶
Bases: BaseModel
Cached API result.
model_dump
¶
Export model as dictionary (Pydantic v2 compatibility).
Source code in src/core/models/track_models.py
TrackDict
¶
Bases: BaseModel
Track information from Apple Music.
get
¶
Get attribute value with default, mimicking dict.get() behavior.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
key
|
str
|
The attribute name to retrieve |
required |
default
|
TrackFieldValue
|
The default value to return if attribute doesn't exist |
None
|
Returns:
| Type | Description |
|---|---|
TrackFieldValue
|
The attribute value if it exists, otherwise the default value |
Source code in src/core/models/track_models.py
copy
¶
Create a copy of the TrackDict with optional field updates.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
**kwargs
|
Any
|
Fields to update in the copy |
{}
|
Returns:
| Type | Description |
|---|---|
TrackDict
|
A new TrackDict instance with updated fields |
Source code in src/core/models/track_models.py
AnalyticsProtocol
¶
Bases: Protocol
Protocol for analytics services providing performance tracking.
Defines the contract for executing wrapped function calls (sync and async) with analytics instrumentation, and batch mode for suppressing console output during heavy processing.
execute_async_wrapped_call
async
¶
Execute an async function with analytics tracking.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
func
|
Callable[..., Any]
|
Async function to execute |
required |
event_type
|
str
|
Type of event for tracking |
required |
*args
|
Any
|
Function arguments |
()
|
**kwargs
|
Any
|
Function keyword arguments |
{}
|
Source code in src/core/models/protocols.py
execute_sync_wrapped_call
¶
Execute a sync function with analytics tracking.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
func
|
Callable[..., Any]
|
Sync function to execute |
required |
event_type
|
str
|
Type of event for tracking |
required |
*args
|
Any
|
Function arguments |
()
|
**kwargs
|
Any
|
Function keyword arguments |
{}
|
Source code in src/core/models/protocols.py
batch_mode
¶
Context manager that suppresses console logging and shows a spinner.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
message
|
str
|
Message to display next to the spinner |
'Processing...'
|
console
|
Console | None
|
Optional Rich Console instance |
None
|
Returns:
| Type | Description |
|---|---|
AbstractAsyncContextManager[Status]
|
Async context manager yielding a Rich Status object |
Source code in src/core/models/protocols.py
AppleScriptClientProtocol
¶
Bases: Protocol
Protocol defining the interface for AppleScript clients.
This protocol allows both real and dry-run implementations to be used interchangeably for executing AppleScript commands.
initialize
async
¶
run_script
async
¶
run_script(
script_name,
arguments=None,
timeout=None,
context_artist=None,
context_album=None,
context_track=None,
label=None,
)
Run an AppleScript file by name.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
script_name
|
str
|
Name of the script file to execute |
required |
arguments
|
list[str] | None
|
Optional arguments to pass to the script |
None
|
timeout
|
float | None
|
Optional timeout in seconds |
None
|
context_artist
|
str | None
|
Artist name for contextual logging (optional) |
None
|
context_album
|
str | None
|
Album name for contextual logging (optional) |
None
|
context_track
|
str | None
|
Track name for contextual logging (optional) |
None
|
label
|
str | None
|
Custom label for logging (defaults to script_name) |
None
|
Returns:
| Type | Description |
|---|---|
str | None
|
Script output or None if no output |
Source code in src/core/models/protocols.py
fetch_tracks_by_ids
async
¶
Fetch tracks by their IDs using fetch_tracks_by_ids.applescript.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
track_ids
|
list[str]
|
List of track IDs to fetch |
required |
batch_size
|
int
|
Maximum number of IDs per batch (default: 1000) |
1000
|
timeout
|
float | None
|
Timeout in seconds for script execution |
None
|
Returns:
| Type | Description |
|---|---|
list[dict[str, str]]
|
List of track dictionaries with metadata |
Source code in src/core/models/protocols.py
fetch_all_track_ids
async
¶
Fetch just track IDs from Music.app (lightweight operation).
This is used by Smart Delta to detect new/removed tracks without fetching full metadata.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
timeout
|
float | None
|
Timeout in seconds for script execution |
None
|
Returns:
| Type | Description |
|---|---|
list[str]
|
List of track ID strings |
Source code in src/core/models/protocols.py
CacheServiceProtocol
¶
Bases: Protocol
Protocol defining the interface for cache services.
This protocol defines methods for both in-memory caching with TTL support and persistent CSV-based caching for album information.
initialize
async
¶
set
¶
Set a value in the cache with optional TTL.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
key_data
|
CacheableKey
|
Key for the cached value (will be hashed if needed) |
required |
value
|
CacheableValue
|
Value to cache |
required |
ttl
|
int | None
|
Time-to-live in seconds (optional) |
None
|
Source code in src/core/models/protocols.py
set_async
async
¶
Asynchronously set a value in the cache with optional TTL.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
key_data
|
CacheableKey
|
Key for the cached value (will be hashed if needed) |
required |
value
|
CacheableValue
|
Value to cache |
required |
ttl
|
int | None
|
Time-to-live in seconds (optional) |
None
|
Source code in src/core/models/protocols.py
get_async
async
¶
get_async(
key_data: Literal["ALL"], compute_func: None = None
) -> list[TrackDict]
get_async(
key_data: str, compute_func: None = None
) -> list[TrackDict] | None
Get a value from cache, optionally computing it if not present.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
key_data
|
CacheableKey
|
Key for the cached value ("ALL" for all tracks) |
required |
compute_func
|
Callable[[], Future[CacheableValue]] | None
|
Optional compute function to calculate value if not cached |
None
|
Returns:
| Type | Description |
|---|---|
list[TrackDict] | CacheableValue
|
Cached value or computed value from factory, or None if not found |
Source code in src/core/models/protocols.py
invalidate
¶
Invalidate (remove) a specific cache entry.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
key_data
|
CacheableKey
|
Key of the cache entry to invalidate |
required |
clear
async
¶
load_cache
async
¶
save_cache
async
¶
get_last_run_timestamp
async
¶
Get the timestamp of the last cache run.
Returns:
| Type | Description |
|---|---|
datetime
|
DateTime of last run, or epoch if never run |
get_album_year_from_cache
async
¶
Get cached album year for an artist/album pair.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
artist
|
str
|
Artist name |
required |
album
|
str
|
Album name |
required |
Returns:
| Type | Description |
|---|---|
str | None
|
Cached year string or None if not found |
Source code in src/core/models/protocols.py
get_album_year_entry_from_cache
async
¶
Get full album cache entry for an artist/album pair.
Use this method when you need to check confidence level before trusting cached data.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
artist
|
str
|
Artist name |
required |
album
|
str
|
Album name |
required |
Returns:
| Type | Description |
|---|---|
AlbumCacheEntry | None
|
Full AlbumCacheEntry or None if not found |
Source code in src/core/models/protocols.py
store_album_year_in_cache
async
¶
Store album year in persistent cache.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
artist
|
str
|
Artist name |
required |
album
|
str
|
Album name |
required |
year
|
str
|
Year to cache |
required |
confidence
|
int
|
Confidence score 0-100 (higher = more trustworthy) |
0
|
Source code in src/core/models/protocols.py
invalidate_album_cache
async
¶
Invalidate cached data for a specific album.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
artist
|
str
|
Artist name |
required |
album
|
str
|
Album name |
required |
invalidate_all_albums
async
¶
sync_cache
async
¶
get_cached_api_result
async
¶
Get cached API result for an artist/album from a specific source.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
artist
|
str
|
Artist name |
required |
album
|
str
|
Album name |
required |
source
|
str
|
API source identifier |
required |
Returns:
| Type | Description |
|---|---|
CachedApiResult | None
|
Cached API result or None if not found |
Source code in src/core/models/protocols.py
set_cached_api_result
async
¶
Cache an API result for an artist/album from a specific source.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
artist
|
str
|
Artist name |
required |
album
|
str
|
Album name |
required |
source
|
str
|
API source identifier |
required |
year
|
str | None
|
Year to cache (None for negative cache) |
required |
metadata
|
dict[str, Any] | None
|
Optional metadata about the result |
None
|
is_negative
|
bool
|
Whether this is a negative cache entry |
False
|
Source code in src/core/models/protocols.py
invalidate_for_track
async
¶
generate_album_key
staticmethod
¶
Generate a unique key for an artist/album pair.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
artist
|
str
|
Artist name |
required |
album
|
str
|
Album name |
required |
Returns:
| Type | Description |
|---|---|
str
|
Unique key string (typically a hash) |
Source code in src/core/models/protocols.py
ExternalApiServiceProtocol
¶
Bases: Protocol
Protocol defining the interface for external API services.
This protocol defines methods for fetching music metadata from external sources like MusicBrainz, Last.fm, and Discogs.
initialize
async
¶
Initialize the external API service.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
force
|
bool
|
Force re-initialization even if already initialized |
False
|
close
async
¶
get_album_year
async
¶
Determine the original release year for an album using optimized API calls and revised scoring.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
artist
|
str
|
Artist name |
required |
album
|
str
|
Album name |
required |
current_library_year
|
str | None
|
Current year in library (optional) |
None
|
earliest_track_added_year
|
int | None
|
Earliest year any track was added to library (optional) |
None
|
Returns:
| Type | Description |
|---|---|
str | None
|
Tuple of (year_string, is_definitive, confidence_score, year_scores) where: |
bool
|
|
int
|
|
dict[str, int]
|
|
tuple[str | None, bool, int, dict[str, int]]
|
|
Source code in src/core/models/protocols.py
get_artist_activity_period
async
¶
Retrieve the period of activity for an artist from MusicBrainz, with caching.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
artist_norm
|
str
|
Normalized artist name |
required |
Returns:
| Type | Description |
|---|---|
tuple[int | None, int | None]
|
Tuple of (start_year, end_year) as integers or (None, None) if not found |
Source code in src/core/models/protocols.py
get_artist_start_year
async
¶
Get artist's career start year with caching and fallback.
Uses MusicBrainz as primary source, iTunes as fallback. Results are cached for performance.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
artist_norm
|
str
|
Normalized artist name |
required |
Returns:
| Type | Description |
|---|---|
int | None
|
Artist's career start year, or None if not found |
Source code in src/core/models/protocols.py
get_year_from_discogs
async
¶
Fetch the earliest release year for an album from Discogs.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
artist
|
str
|
Artist name |
required |
album
|
str
|
Album name |
required |
Returns:
| Type | Description |
|---|---|
str | None
|
Year string or None if not found |
Source code in src/core/models/protocols.py
PendingVerificationServiceProtocol
¶
Bases: Protocol
Protocol defining the interface for pending verification services.
This protocol defines methods for managing albums that need manual verification or have pending updates.
initialize
async
¶
mark_for_verification
async
¶
Mark an album for future verification.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
artist
|
str
|
Artist name |
required |
album
|
str
|
Album name |
required |
reason
|
str
|
Reason for marking for verification |
'no_year_found'
|
metadata
|
dict[str, Any] | None
|
Additional metadata to store |
None
|
recheck_days
|
int | None
|
Optional override for verification interval in days |
None
|
Source code in src/core/models/protocols.py
remove_from_pending
async
¶
Remove an album from pending verification.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
artist
|
str
|
Artist name |
required |
album
|
str
|
Album name |
required |
get_entry
async
¶
Get pending entry for artist/album if exists.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
artist
|
str
|
Artist name |
required |
album
|
str
|
Album name |
required |
Returns:
| Type | Description |
|---|---|
PendingAlbumEntry | None
|
PendingAlbumEntry if found, None otherwise. |
Source code in src/core/models/protocols.py
get_attempt_count
async
¶
Get current verification attempt count for an album.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
artist
|
str
|
Artist name |
required |
album
|
str
|
Album name |
required |
Returns:
| Type | Description |
|---|---|
int
|
Number of verification attempts made (0 if not in pending list). |
Source code in src/core/models/protocols.py
is_verification_needed
async
¶
Check if an album needs verification now.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
artist
|
str
|
Artist name |
required |
album
|
str
|
Album name |
required |
Returns:
| Type | Description |
|---|---|
bool
|
True if the verification period has elapsed, False otherwise. |
Source code in src/core/models/protocols.py
get_all_pending_albums
async
¶
Get all pending albums.
Returns:
| Type | Description |
|---|---|
list[PendingAlbumEntry]
|
List of PendingAlbumEntry objects |
generate_problematic_albums_report
async
¶
Generate report of albums that failed to get year after multiple attempts.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
min_attempts
|
int
|
Minimum number of attempts to consider problematic |
3
|
Returns:
| Type | Description |
|---|---|
int
|
Number of problematic albums found |
Source code in src/core/models/protocols.py
should_auto_verify
async
¶
Check if automatic pending verification should run.
Returns True if: - auto_verify_days has passed since last verification - No previous verification exists - auto_verify_days > 0 (feature enabled)
Returns:
| Type | Description |
|---|---|
bool
|
True if auto-verify should run, False otherwise. |
Source code in src/core/models/protocols.py
RateLimiterProtocol
¶
Bases: Protocol
Protocol defining the interface for rate limiting services.
This protocol ensures API calls respect rate limits and prevent overwhelming external services.