Skip to content

track_models

Pydantic models for configuration and data validation.

MBArtist

Bases: TypedDict

Type definition for MusicBrainz artist data structure.

MBArtistCredit

Bases: TypedDict

Type definition for MusicBrainz artist credit data structure.

LogLevel

Bases: StrEnum

Log level enumeration.

PreferredApi

Bases: StrEnum

Preferred API enumeration.

ChangeDisplayMode

Bases: StrEnum

Change display mode enumeration.

PythonSettings

Bases: BaseModel

Python environment settings.

AppleScriptTimeoutsConfig

Bases: BaseModel

Per-operation AppleScript timeout overrides.

AppleScriptRateLimitConfig

Bases: BaseModel

AppleScript operation rate limiter settings.

ExperimentalConfig

Bases: BaseModel

Experimental feature toggles.

AppleScriptRetryConfig

Bases: BaseModel

AppleScript operation retry policy.

BatchProcessingConfig

Bases: BaseModel

Batch processing size configuration.

ArtistRenamerConfig

Bases: BaseModel

Artist renamer configuration.

PendingVerificationConfig

Bases: BaseModel

Pending verification auto-run settings.

AlbumTypeDetectionConfig

Bases: BaseModel

Album type detection patterns for year fallback logic.

Semantics for pattern fields
  • None (default): use built-in defaults
  • [] (empty list): explicitly disable the category
  • ["pattern", ...]: use the provided patterns

LibrarySnapshotConfig

Bases: BaseModel

Library snapshot persistence settings.

CleaningConfig

Bases: BaseModel

Cleaning configuration.

TrackCleaningException

Bases: BaseModel

Track cleaning exception.

ExceptionsConfig

Bases: BaseModel

Exceptions configuration.

DatabaseVerificationConfig

Bases: BaseModel

Database verification configuration.

DevelopmentConfig

Bases: BaseModel

Development configuration.

parse_test_artists classmethod

parse_test_artists(v)

Convert comma-separated string, list, or tuple to list of strings.

Supports formats: - YAML list: [ Amon Amarth, Children of Bodom ] - Comma string: "Amon Amarth, Children of Bodom" - Tuple: ("Amon Amarth", "Children of Bodom")

Raises:

Type Description
ValueError

If input is not a string, list, or tuple.

TypeError

If list/tuple contains non-string elements.

Source code in src/core/models/track_models.py
@field_validator("test_artists", mode="before")
@classmethod
def parse_test_artists(cls, v: str | list[str] | tuple[str, ...]) -> list[str]:
    """Convert comma-separated string, list, or tuple to list of strings.

    Supports formats:
    - YAML list: [ Amon Amarth, Children of Bodom ]
    - Comma string: "Amon Amarth, Children of Bodom"
    - Tuple: ("Amon Amarth", "Children of Bodom")

    Raises:
        ValueError: If input is not a string, list, or tuple.
        TypeError: If list/tuple contains non-string elements.
    """
    if isinstance(v, str):
        return [a.strip() for a in v.split(",") if a.strip()]
    if isinstance(v, (list, tuple)):
        result = []
        for i, item in enumerate(v):
            if not isinstance(item, str):
                msg = f"test_artists[{i}] must be str, got {type(item).__name__}"
                raise TypeError(msg)
            if stripped := item.strip():
                result.append(stripped)
        return result
    msg = f"test_artists must be a string, list, or tuple, got {type(v).__name__}"
    raise ValueError(msg)

LogLevelsConfig

Bases: BaseModel

Log levels configuration.

normalize_log_level classmethod

normalize_log_level(value)

Accept case-insensitive log level names (e.g. 'debug' -> 'DEBUG').

Source code in src/core/models/track_models.py
@field_validator("console", "main_file", "analytics_file", mode="before")
@classmethod
def normalize_log_level(cls, value: str) -> str:
    """Accept case-insensitive log level names (e.g. 'debug' -> 'DEBUG')."""
    return value.upper() if isinstance(value, str) else value

LoggingConfig

Bases: BaseModel

Logging configuration.

DurationThresholds

Bases: BaseModel

Duration thresholds for analytics.

AnalyticsConfig

Bases: BaseModel

Analytics configuration.

GenreUpdateConfig

Bases: BaseModel

Genre update configuration.

ApiAuthConfig

Bases: BaseModel

API authentication configuration.

RateLimitsConfig

Bases: BaseModel

Rate limits configuration.

ProcessingConfig

Bases: BaseModel

Processing configuration for year retrieval.

LogicConfig

Bases: BaseModel

Year retrieval logic configuration.

ReissueDetectionConfig

Bases: BaseModel

Reissue detection configuration.

ScoringConfig

Bases: BaseModel

Scoring parameters for release year evaluation.

All numeric fields use int to match config.yaml values and downstream consumers (ReleaseScorer uses them as-is without casts). Penalties are constrained to le=0; bonuses are unconstrained.

FallbackConfig

Bases: BaseModel

Year retrieval fallback settings.

ScriptApiPriority

Bases: BaseModel

API priority configuration for a specific script type.

YearRetrievalConfig

Bases: BaseModel

Year retrieval configuration.

CachingConfig

Bases: BaseModel

Caching configuration.

ReportingConfig

Bases: BaseModel

Reporting configuration.

AppConfig

Bases: BaseModel

Main application configuration model.

migrate_legacy_test_artists

migrate_legacy_test_artists()

Migrate top-level test_artists into development.test_artists.

Old configs may have a top-level test_artists key alongside an empty development.test_artists. This validator copies the legacy value so that consumers reading config.development.test_artists get the expected list.

Source code in src/core/models/track_models.py
@model_validator(mode="after")
def migrate_legacy_test_artists(self) -> AppConfig:
    """Migrate top-level test_artists into development.test_artists.

    Old configs may have a top-level ``test_artists`` key alongside an empty
    ``development.test_artists``.  This validator copies the legacy value so
    that consumers reading ``config.development.test_artists`` get the
    expected list.
    """
    if self.test_artists:
        if self.development.test_artists:
            warnings.warn(
                "Both top-level 'test_artists' and 'development.test_artists' are set. Top-level value is ignored; using development section.",
                DeprecationWarning,
                stacklevel=2,
            )
        else:
            self.development.test_artists = list(self.test_artists)
            warnings.warn(
                "Top-level 'test_artists' is deprecated. Move it to 'development.test_artists' in your config file.",
                DeprecationWarning,
                stacklevel=2,
            )
    return self

TrackDict

Bases: BaseModel

Track information from Apple Music.

get

get(key, default=None)

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
def get(self, key: str, default: TrackFieldValue = None) -> TrackFieldValue:
    """Get attribute value with default, mimicking dict.get() behavior.

    Args:
        key: The attribute name to retrieve
        default: The default value to return if attribute doesn't exist

    Returns:
        The attribute value if it exists, otherwise the default value

    """
    try:
        # First, try to get the field value using getattr
        value = getattr(self, key)
    except AttributeError:
        # For Pydantic v1 with extra="allow", additional fields are stored in __dict__
        if key in self.__dict__:
            value = self.__dict__[key]
            return default if value is None and default is not None else value
        return default

    # Return the value, but if it's None, and we have a non-None default, use default
    return default if value is None and default is not None else value

copy

copy(**kwargs)

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
def copy(self, **kwargs: Any) -> TrackDict:
    """Create a copy of the TrackDict with optional field updates.

    Args:
        **kwargs: Fields to update in the copy

    Returns:
        A new TrackDict instance with updated fields

    """
    # Pydantic v2 model_dump() includes extra fields automatically
    data = self.model_dump()
    data.update(kwargs)
    return TrackDict(**data)

ChangeLogEntry

Bases: BaseModel

Change log entry for track updates.

Supports genre updates, year updates, and metadata cleaning with optional fields.

CachedApiResult

Bases: BaseModel

Cached API result.

model_dump

model_dump(**_kwargs)

Export model as dictionary (Pydantic v2 compatibility).

Source code in src/core/models/track_models.py
def model_dump(self, **_kwargs: Any) -> dict[str, Any]:
    """Export model as dictionary (Pydantic v2 compatibility)."""
    return {
        "artist": self.artist,
        "album": self.album,
        "year": self.year,
        "source": self.source,
        "timestamp": self.timestamp,
        "ttl": self.ttl,
        "metadata": self.metadata,
        "api_response": self.api_response,
    }

ScriptAction

Bases: BaseModel

AppleScript action definition.

CodeAction

Bases: BaseModel

AppleScript code action definition.

ScriptActionExtended

Bases: BaseModel

Extended script action with type and path.

CodeActionExtended

Bases: BaseModel

Extended code action with type.

MusicBrainzArtist

Bases: BaseModel

MusicBrainz artist information.

MusicBrainzReleaseGroup

Bases: BaseModel

MusicBrainz release group information.

MusicBrainzRelease

Bases: BaseModel

MusicBrainz release information.

MusicBrainzSearchResult

Bases: BaseModel

MusicBrainz search result.

DiscogsArtist

Bases: BaseModel

Discogs artist information.