Skip to content

List Provider API

AniBridge list provider base classes package.

ListEntity dataclass

Bases: ABC

Base class for list entities.

Source code in .venv/lib/python3.14/site-packages/anibridge/list/base.py
@dataclass(slots=True, eq=False)
class ListEntity[ProviderT: ListProvider](ABC):
    """Base class for list entities."""

    _provider: ProviderT = field(repr=False, compare=False)
    _key: str
    _title: str = field(compare=False)

    @property
    def key(self) -> str:
        """Return the unique key for this entity."""
        return self._key

    def provider(self) -> ProviderT:
        """Return the provider associated with this entity."""
        return self._provider

    @property
    def title(self) -> str:
        """Return the title of this entity."""
        return self._title

    def __hash__(self) -> int:
        """Compute a hash based on the provider namespace, class name, and key."""
        return hash((self._provider.NAMESPACE, self.__class__.__name__, self.key))

    def __eq__(self, other: object) -> bool:
        """Check equality with another ListEntity based on provider and key."""
        if other.__class__ is not self.__class__:
            return NotImplemented
        other_ent = cast(ListEntity, other)
        return (
            self._provider.NAMESPACE == other_ent._provider.NAMESPACE
            and self.key == other_ent.key
        )

    def __repr__(self) -> str:
        """Return a string representation of the ListEntity."""
        return (
            f"<{self.__class__.__name__}:{self._provider.NAMESPACE}:{self.key}:"
            f"{self.title[:32]}>"
        )

key property

Return the unique key for this entity.

title property

Return the title of this entity.

__eq__(other)

Check equality with another ListEntity based on provider and key.

Source code in .venv/lib/python3.14/site-packages/anibridge/list/base.py
def __eq__(self, other: object) -> bool:
    """Check equality with another ListEntity based on provider and key."""
    if other.__class__ is not self.__class__:
        return NotImplemented
    other_ent = cast(ListEntity, other)
    return (
        self._provider.NAMESPACE == other_ent._provider.NAMESPACE
        and self.key == other_ent.key
    )

__hash__()

Compute a hash based on the provider namespace, class name, and key.

Source code in .venv/lib/python3.14/site-packages/anibridge/list/base.py
def __hash__(self) -> int:
    """Compute a hash based on the provider namespace, class name, and key."""
    return hash((self._provider.NAMESPACE, self.__class__.__name__, self.key))

__repr__()

Return a string representation of the ListEntity.

Source code in .venv/lib/python3.14/site-packages/anibridge/list/base.py
def __repr__(self) -> str:
    """Return a string representation of the ListEntity."""
    return (
        f"<{self.__class__.__name__}:{self._provider.NAMESPACE}:{self.key}:"
        f"{self.title[:32]}>"
    )

provider()

Return the provider associated with this entity.

Source code in .venv/lib/python3.14/site-packages/anibridge/list/base.py
def provider(self) -> ProviderT:
    """Return the provider associated with this entity."""
    return self._provider

ListEntry dataclass

Bases: ListEntity[ProviderT], ABC

Base class for list entries for a given media item.

Source code in .venv/lib/python3.14/site-packages/anibridge/list/base.py
class ListEntry[ProviderT: ListProvider](ListEntity[ProviderT], ABC):
    """Base class for list entries for a given media item."""

    @property
    @abstractmethod
    def progress(self) -> int | None:
        """Progress integer (e.g., episodes watched)."""
        ...

    @progress.setter
    @abstractmethod
    def progress(self, value: int | None) -> None: ...

    @property
    @abstractmethod
    def repeats(self) -> int | None:
        """Repeat count for the entry."""
        ...

    @repeats.setter
    @abstractmethod
    def repeats(self, value: int | None) -> None: ...

    @property
    @abstractmethod
    def review(self) -> str | None:
        """User review text, if any."""
        ...

    @review.setter
    @abstractmethod
    def review(self, value: str | None) -> None: ...

    @property
    @abstractmethod
    def status(self) -> ListStatus | None:
        """Watch status for the entry."""
        ...

    @status.setter
    @abstractmethod
    def status(self, value: ListStatus | None) -> None:
        """Update the status for the entry."""
        ...

    @property
    @abstractmethod
    def user_rating(self) -> int | None:
        """User rating on a 0-100 scale."""
        ...

    @user_rating.setter
    @abstractmethod
    def user_rating(self, value: int | None) -> None:
        """Update the user rating for the entry."""
        ...

    @property
    @abstractmethod
    def started_at(self) -> datetime | None:
        """Timestamp when the user started the entry (timezone-aware)."""
        ...

    @started_at.setter
    @abstractmethod
    def started_at(self, value: datetime | None) -> None:
        """Update the started_at timestamp for the entry."""
        ...

    @property
    @abstractmethod
    def finished_at(self) -> datetime | None:
        """Timestamp when the user first completed the entry (timezone-aware)."""
        ...

    @finished_at.setter
    @abstractmethod
    def finished_at(self, value: datetime | None) -> None:
        """Update the finished_at timestamp for the entry."""
        ...

    @abstractmethod
    def media(self) -> ListMedia[ProviderT]:
        """Get the media item associated with this entry.

        For an efficient implementation, this should return a cached media item if
        possible, rather than fetching it anew each time.

        Returns:
            ListMedia: The media item associated with this entry.
        """
        ...

finished_at abstractmethod property writable

Timestamp when the user first completed the entry (timezone-aware).

key property

Return the unique key for this entity.

progress abstractmethod property writable

Progress integer (e.g., episodes watched).

repeats abstractmethod property writable

Repeat count for the entry.

review abstractmethod property writable

User review text, if any.

started_at abstractmethod property writable

Timestamp when the user started the entry (timezone-aware).

status abstractmethod property writable

Watch status for the entry.

title property

Return the title of this entity.

user_rating abstractmethod property writable

User rating on a 0-100 scale.

__eq__(other)

Check equality with another ListEntity based on provider and key.

Source code in .venv/lib/python3.14/site-packages/anibridge/list/base.py
def __eq__(self, other: object) -> bool:
    """Check equality with another ListEntity based on provider and key."""
    if other.__class__ is not self.__class__:
        return NotImplemented
    other_ent = cast(ListEntity, other)
    return (
        self._provider.NAMESPACE == other_ent._provider.NAMESPACE
        and self.key == other_ent.key
    )

__hash__()

Compute a hash based on the provider namespace, class name, and key.

Source code in .venv/lib/python3.14/site-packages/anibridge/list/base.py
def __hash__(self) -> int:
    """Compute a hash based on the provider namespace, class name, and key."""
    return hash((self._provider.NAMESPACE, self.__class__.__name__, self.key))

__repr__()

Return a string representation of the ListEntity.

Source code in .venv/lib/python3.14/site-packages/anibridge/list/base.py
def __repr__(self) -> str:
    """Return a string representation of the ListEntity."""
    return (
        f"<{self.__class__.__name__}:{self._provider.NAMESPACE}:{self.key}:"
        f"{self.title[:32]}>"
    )

media() abstractmethod

Get the media item associated with this entry.

For an efficient implementation, this should return a cached media item if possible, rather than fetching it anew each time.

Returns:

Name Type Description
ListMedia ListMedia[ProviderT]

The media item associated with this entry.

Source code in .venv/lib/python3.14/site-packages/anibridge/list/base.py
@abstractmethod
def media(self) -> ListMedia[ProviderT]:
    """Get the media item associated with this entry.

    For an efficient implementation, this should return a cached media item if
    possible, rather than fetching it anew each time.

    Returns:
        ListMedia: The media item associated with this entry.
    """
    ...

provider()

Return the provider associated with this entity.

Source code in .venv/lib/python3.14/site-packages/anibridge/list/base.py
def provider(self) -> ProviderT:
    """Return the provider associated with this entity."""
    return self._provider

ListMedia dataclass

Bases: ListEntity[ProviderT], ABC

Base class for media items in a provider list.

Subclasses should call the base constructor and may override properties if they need custom behaviour; defaults store values provided at init time.

Source code in .venv/lib/python3.14/site-packages/anibridge/list/base.py
class ListMedia[ProviderT: ListProvider](ListEntity[ProviderT], ABC):
    """Base class for media items in a provider list.

    Subclasses should call the base constructor and may override properties if
    they need custom behaviour; defaults store values provided at init time.
    """

    @property
    def external_url(self) -> str | None:
        """URL to the provider's media item, if available."""
        return None

    @property
    def labels(self) -> Sequence[str]:
        """Display labels such as season or release year."""
        return ()

    @property
    @abstractmethod
    def media_type(self) -> ListMediaType:
        """Type of media (e.g., TV, MOVIE)."""
        ...

    @property
    def poster_image(self) -> str | None:
        """Poster or cover image URL, if provided by the provider."""
        return None

    @property
    @abstractmethod
    def total_units(self) -> int | None:
        """Total number of units (episodes/chapters) for the media."""
        ...

external_url property

URL to the provider's media item, if available.

key property

Return the unique key for this entity.

labels property

Display labels such as season or release year.

media_type abstractmethod property

Type of media (e.g., TV, MOVIE).

poster_image property

Poster or cover image URL, if provided by the provider.

title property

Return the title of this entity.

total_units abstractmethod property

Total number of units (episodes/chapters) for the media.

__eq__(other)

Check equality with another ListEntity based on provider and key.

Source code in .venv/lib/python3.14/site-packages/anibridge/list/base.py
def __eq__(self, other: object) -> bool:
    """Check equality with another ListEntity based on provider and key."""
    if other.__class__ is not self.__class__:
        return NotImplemented
    other_ent = cast(ListEntity, other)
    return (
        self._provider.NAMESPACE == other_ent._provider.NAMESPACE
        and self.key == other_ent.key
    )

__hash__()

Compute a hash based on the provider namespace, class name, and key.

Source code in .venv/lib/python3.14/site-packages/anibridge/list/base.py
def __hash__(self) -> int:
    """Compute a hash based on the provider namespace, class name, and key."""
    return hash((self._provider.NAMESPACE, self.__class__.__name__, self.key))

__repr__()

Return a string representation of the ListEntity.

Source code in .venv/lib/python3.14/site-packages/anibridge/list/base.py
def __repr__(self) -> str:
    """Return a string representation of the ListEntity."""
    return (
        f"<{self.__class__.__name__}:{self._provider.NAMESPACE}:{self.key}:"
        f"{self.title[:32]}>"
    )

provider()

Return the provider associated with this entity.

Source code in .venv/lib/python3.14/site-packages/anibridge/list/base.py
def provider(self) -> ProviderT:
    """Return the provider associated with this entity."""
    return self._provider

ListMediaType

Bases: StrEnum

Supported media types in a list.

Source code in .venv/lib/python3.14/site-packages/anibridge/list/base.py
class ListMediaType(StrEnum):
    """Supported media types in a list."""

    TV = "TV"
    MOVIE = "MOVIE"

ListProvider

Bases: ABC

Abstract base provider that exposes a user media list.

Source code in .venv/lib/python3.14/site-packages/anibridge/list/base.py
class ListProvider(ABC):
    """Abstract base provider that exposes a user media list."""

    NAMESPACE: ClassVar[str]
    MAPPING_PROVIDERS: ClassVar[frozenset[str]]

    def __init__(self, *, logger: ProviderLogger, config: dict | None = None) -> None:
        """Initialize the provider with optional configuration.

        Args:
            logger (ProviderLogger): Application logger injected by AniBridge.
            config (dict | None): Any configuration options that were detected with the
                provider's namespace as a prefix.
        """
        self.log = logger.getChild(f"list.{self.NAMESPACE}")
        self.config: dict = config or {}

    async def initialize(self) -> None:
        """Asynchronous initialization hook.

        Put any async logic that should be run after construction here.
        """
        return None

    async def backup_list(self) -> str:
        """Backup the entire list from the provider.

        It is up to the implementation to decide the format of the backup data. Whatever
        format, it should be serializable/deserializable as a string.

        Backup capabilities are optional. If a provider does not support backups, this
        method should raise a NotImplementedError.

        Returns:
            str: A serialized string representation of all list entries.
        """
        raise NotImplementedError(f"{self.NAMESPACE} does not support backup_list()")

    async def clear_cache(self) -> None:
        """Clear any cached data held by the provider.

        For more efficient implementations, it is a good idea to cache data
        fetched from the provider to minimize network requests. AniBridge uses
        this method occasionally to clear such caches.
        """
        return None

    async def close(self) -> None:
        """Close the provider and release resources."""
        return None

    @abstractmethod
    async def delete_entry(self, key: str) -> None:
        """Delete a list entry by its media key.

        Args:
            key (str): The unique key of the media item to delete.
        """
        ...

    @abstractmethod
    async def resolve_mapping_descriptors(
        self, descriptors: Sequence[MappingDescriptor]
    ) -> Sequence[ListTarget]:
        """Resolve mapping descriptors into list media keys.

        Implementations should return one ListTarget for each mapping descriptor that
        can be resolved into a list media key. Multiple list keys may be returned for a
        single descriptor.

        Args:
            descriptors (Sequence[MappingDescriptor]): Mapping descriptors to resolve.

        Returns:
            Sequence[ListTarget]: The resolved descriptor/key pairs.
        """
        ...

    @abstractmethod
    async def get_entry(self, key: str) -> ListEntry[Self] | None:
        """Retrieve a list entry by its media key.

        Only return None if the media item does not exist on the provider.

        Args:
            key (str): The unique key of the media item to retrieve.

        Returns:
            ListEntry | None: The list entry if found, otherwise None.
        """
        ...

    async def get_entries_batch(
        self, keys: Sequence[str]
    ) -> Sequence[ListEntry[Self] | None]:
        """Retrieve multiple list entries by their media keys.

        The order of the returned sequence must match the order of the input keys.

        Args:
            keys (Sequence[str]): The unique keys of the media items to retrieve.

        Returns:
            Sequence[ListEntry | None]: A sequence of list entries, with None for any
                not found.
        """
        entries: list[ListEntry[Self] | None] = []
        for key in keys:
            try:
                entry = await self.get_entry(key)
            except Exception:
                self.log.exception("Error fetching entry for key '%s'", key)
                entry = None
            entries.append(entry)
        return entries

    async def restore_list(self, backup: str) -> None:
        """Restore list entries from a backup string.

        The format of the backup string is determined by the implementation
        of `backup_list`.

        Args:
            backup (str): The serialized string representation of the list entries.
        """
        return None

    async def search(self, query: str) -> Sequence[ListEntry[Self]]:
        """Search the provider for entries matching the query.

        Args:
            query (str): The search query string.

        Returns:
            Sequence[ListEntry]: A sequence of matching list entries.
        """
        return []

    @abstractmethod
    async def update_entry(
        self, key: str, entry: ListEntry[Self]
    ) -> ListEntry[Self] | None:
        """Update a list entry with new information.

        Args:
            key (str): The unique key of the media item to update.
            entry (ListEntry): The updated entry information.

        Returns:
            ListEntry | None: The updated list entry, or None if the update failed.
        """
        ...

    async def update_entries_batch(
        self, entries: Sequence[ListEntry[Self]]
    ) -> Sequence[ListEntry[Self] | None]:
        """Update multiple list entries in a single operation.

        Args:
            entries (Sequence[ListEntry]): The list entries to update.

        Returns:
            Sequence[ListEntry | None]: A sequence of updated list entries, with None
                for any that could not be updated.
        """
        updated_entries: list[ListEntry[Self] | None] = []
        for entry in entries:
            try:
                updated_entry = await self.update_entry(entry.media().key, entry)
            except Exception:
                self.log.exception(
                    "Error updating entry for key '%s'", entry.media().key
                )
                updated_entry = None
            updated_entries.append(updated_entry)
        return updated_entries

    @abstractmethod
    def user(self) -> ListUser | None:
        """Return the associated user object, if any.

        Returns:
            User | None: The associated user object, if any.
        """
        ...

__init__(*, logger, config=None)

Initialize the provider with optional configuration.

Parameters:

Name Type Description Default
logger ProviderLogger

Application logger injected by AniBridge.

required
config dict | None

Any configuration options that were detected with the provider's namespace as a prefix.

None
Source code in .venv/lib/python3.14/site-packages/anibridge/list/base.py
def __init__(self, *, logger: ProviderLogger, config: dict | None = None) -> None:
    """Initialize the provider with optional configuration.

    Args:
        logger (ProviderLogger): Application logger injected by AniBridge.
        config (dict | None): Any configuration options that were detected with the
            provider's namespace as a prefix.
    """
    self.log = logger.getChild(f"list.{self.NAMESPACE}")
    self.config: dict = config or {}

backup_list() async

Backup the entire list from the provider.

It is up to the implementation to decide the format of the backup data. Whatever format, it should be serializable/deserializable as a string.

Backup capabilities are optional. If a provider does not support backups, this method should raise a NotImplementedError.

Returns:

Name Type Description
str str

A serialized string representation of all list entries.

Source code in .venv/lib/python3.14/site-packages/anibridge/list/base.py
async def backup_list(self) -> str:
    """Backup the entire list from the provider.

    It is up to the implementation to decide the format of the backup data. Whatever
    format, it should be serializable/deserializable as a string.

    Backup capabilities are optional. If a provider does not support backups, this
    method should raise a NotImplementedError.

    Returns:
        str: A serialized string representation of all list entries.
    """
    raise NotImplementedError(f"{self.NAMESPACE} does not support backup_list()")

clear_cache() async

Clear any cached data held by the provider.

For more efficient implementations, it is a good idea to cache data fetched from the provider to minimize network requests. AniBridge uses this method occasionally to clear such caches.

Source code in .venv/lib/python3.14/site-packages/anibridge/list/base.py
async def clear_cache(self) -> None:
    """Clear any cached data held by the provider.

    For more efficient implementations, it is a good idea to cache data
    fetched from the provider to minimize network requests. AniBridge uses
    this method occasionally to clear such caches.
    """
    return None

close() async

Close the provider and release resources.

Source code in .venv/lib/python3.14/site-packages/anibridge/list/base.py
async def close(self) -> None:
    """Close the provider and release resources."""
    return None

delete_entry(key) abstractmethod async

Delete a list entry by its media key.

Parameters:

Name Type Description Default
key str

The unique key of the media item to delete.

required
Source code in .venv/lib/python3.14/site-packages/anibridge/list/base.py
@abstractmethod
async def delete_entry(self, key: str) -> None:
    """Delete a list entry by its media key.

    Args:
        key (str): The unique key of the media item to delete.
    """
    ...

get_entries_batch(keys) async

Retrieve multiple list entries by their media keys.

The order of the returned sequence must match the order of the input keys.

Parameters:

Name Type Description Default
keys Sequence[str]

The unique keys of the media items to retrieve.

required

Returns:

Type Description
Sequence[ListEntry[Self] | None]

Sequence[ListEntry | None]: A sequence of list entries, with None for any not found.

Source code in .venv/lib/python3.14/site-packages/anibridge/list/base.py
async def get_entries_batch(
    self, keys: Sequence[str]
) -> Sequence[ListEntry[Self] | None]:
    """Retrieve multiple list entries by their media keys.

    The order of the returned sequence must match the order of the input keys.

    Args:
        keys (Sequence[str]): The unique keys of the media items to retrieve.

    Returns:
        Sequence[ListEntry | None]: A sequence of list entries, with None for any
            not found.
    """
    entries: list[ListEntry[Self] | None] = []
    for key in keys:
        try:
            entry = await self.get_entry(key)
        except Exception:
            self.log.exception("Error fetching entry for key '%s'", key)
            entry = None
        entries.append(entry)
    return entries

get_entry(key) abstractmethod async

Retrieve a list entry by its media key.

Only return None if the media item does not exist on the provider.

Parameters:

Name Type Description Default
key str

The unique key of the media item to retrieve.

required

Returns:

Type Description
ListEntry[Self] | None

ListEntry | None: The list entry if found, otherwise None.

Source code in .venv/lib/python3.14/site-packages/anibridge/list/base.py
@abstractmethod
async def get_entry(self, key: str) -> ListEntry[Self] | None:
    """Retrieve a list entry by its media key.

    Only return None if the media item does not exist on the provider.

    Args:
        key (str): The unique key of the media item to retrieve.

    Returns:
        ListEntry | None: The list entry if found, otherwise None.
    """
    ...

initialize() async

Asynchronous initialization hook.

Put any async logic that should be run after construction here.

Source code in .venv/lib/python3.14/site-packages/anibridge/list/base.py
async def initialize(self) -> None:
    """Asynchronous initialization hook.

    Put any async logic that should be run after construction here.
    """
    return None

resolve_mapping_descriptors(descriptors) abstractmethod async

Resolve mapping descriptors into list media keys.

Implementations should return one ListTarget for each mapping descriptor that can be resolved into a list media key. Multiple list keys may be returned for a single descriptor.

Parameters:

Name Type Description Default
descriptors Sequence[MappingDescriptor]

Mapping descriptors to resolve.

required

Returns:

Type Description
Sequence[ListTarget]

Sequence[ListTarget]: The resolved descriptor/key pairs.

Source code in .venv/lib/python3.14/site-packages/anibridge/list/base.py
@abstractmethod
async def resolve_mapping_descriptors(
    self, descriptors: Sequence[MappingDescriptor]
) -> Sequence[ListTarget]:
    """Resolve mapping descriptors into list media keys.

    Implementations should return one ListTarget for each mapping descriptor that
    can be resolved into a list media key. Multiple list keys may be returned for a
    single descriptor.

    Args:
        descriptors (Sequence[MappingDescriptor]): Mapping descriptors to resolve.

    Returns:
        Sequence[ListTarget]: The resolved descriptor/key pairs.
    """
    ...

restore_list(backup) async

Restore list entries from a backup string.

The format of the backup string is determined by the implementation of backup_list.

Parameters:

Name Type Description Default
backup str

The serialized string representation of the list entries.

required
Source code in .venv/lib/python3.14/site-packages/anibridge/list/base.py
async def restore_list(self, backup: str) -> None:
    """Restore list entries from a backup string.

    The format of the backup string is determined by the implementation
    of `backup_list`.

    Args:
        backup (str): The serialized string representation of the list entries.
    """
    return None

search(query) async

Search the provider for entries matching the query.

Parameters:

Name Type Description Default
query str

The search query string.

required

Returns:

Type Description
Sequence[ListEntry[Self]]

Sequence[ListEntry]: A sequence of matching list entries.

Source code in .venv/lib/python3.14/site-packages/anibridge/list/base.py
async def search(self, query: str) -> Sequence[ListEntry[Self]]:
    """Search the provider for entries matching the query.

    Args:
        query (str): The search query string.

    Returns:
        Sequence[ListEntry]: A sequence of matching list entries.
    """
    return []

update_entries_batch(entries) async

Update multiple list entries in a single operation.

Parameters:

Name Type Description Default
entries Sequence[ListEntry]

The list entries to update.

required

Returns:

Type Description
Sequence[ListEntry[Self] | None]

Sequence[ListEntry | None]: A sequence of updated list entries, with None for any that could not be updated.

Source code in .venv/lib/python3.14/site-packages/anibridge/list/base.py
async def update_entries_batch(
    self, entries: Sequence[ListEntry[Self]]
) -> Sequence[ListEntry[Self] | None]:
    """Update multiple list entries in a single operation.

    Args:
        entries (Sequence[ListEntry]): The list entries to update.

    Returns:
        Sequence[ListEntry | None]: A sequence of updated list entries, with None
            for any that could not be updated.
    """
    updated_entries: list[ListEntry[Self] | None] = []
    for entry in entries:
        try:
            updated_entry = await self.update_entry(entry.media().key, entry)
        except Exception:
            self.log.exception(
                "Error updating entry for key '%s'", entry.media().key
            )
            updated_entry = None
        updated_entries.append(updated_entry)
    return updated_entries

update_entry(key, entry) abstractmethod async

Update a list entry with new information.

Parameters:

Name Type Description Default
key str

The unique key of the media item to update.

required
entry ListEntry

The updated entry information.

required

Returns:

Type Description
ListEntry[Self] | None

ListEntry | None: The updated list entry, or None if the update failed.

Source code in .venv/lib/python3.14/site-packages/anibridge/list/base.py
@abstractmethod
async def update_entry(
    self, key: str, entry: ListEntry[Self]
) -> ListEntry[Self] | None:
    """Update a list entry with new information.

    Args:
        key (str): The unique key of the media item to update.
        entry (ListEntry): The updated entry information.

    Returns:
        ListEntry | None: The updated list entry, or None if the update failed.
    """
    ...

user() abstractmethod

Return the associated user object, if any.

Returns:

Type Description
ListUser | None

User | None: The associated user object, if any.

Source code in .venv/lib/python3.14/site-packages/anibridge/list/base.py
@abstractmethod
def user(self) -> ListUser | None:
    """Return the associated user object, if any.

    Returns:
        User | None: The associated user object, if any.
    """
    ...

ListStatus

Bases: StrEnum

Supported statuses for media items in a list.

Source code in .venv/lib/python3.14/site-packages/anibridge/list/base.py
class ListStatus(StrEnum):
    """Supported statuses for media items in a list."""

    COMPLETED = "completed"
    CURRENT = "current"
    DROPPED = "dropped"
    PAUSED = "paused"
    PLANNING = "planning"
    REPEATING = "repeating"

    __PRIORITY: ClassVar[dict[str, int]] = {
        "completed": 3,
        "repeating": 3,
        "current": 2,
        "paused": 2,
        "dropped": 2,
        "planning": 1,
    }

    @property
    def priority(self) -> int:
        """Get the priority of the ListStatus for comparison purposes."""
        return self.__PRIORITY[self.value]

    def __eq__(self, other: object) -> bool:
        """Check equality with another ListStatus (not based on priority)."""
        if not isinstance(other, ListStatus):
            return NotImplemented
        return self.value == other.value

    def __lt__(self, other: object) -> bool:
        """Check if this ListStatus has lower priority than another."""
        if not isinstance(other, ListStatus):
            return NotImplemented
        return self.priority < other.priority

    def __le__(self, other: object) -> bool:
        """Check if this ListStatus has lower or equal priority than another."""
        if not isinstance(other, ListStatus):
            return NotImplemented
        return self.priority <= other.priority

    def __gt__(self, other: object) -> bool:
        """Check if this ListStatus has higher priority than another."""
        if not isinstance(other, ListStatus):
            return NotImplemented
        return self.priority > other.priority

    def __ge__(self, other: object) -> bool:
        """Check if this ListStatus has higher or equal priority than another."""
        if not isinstance(other, ListStatus):
            return NotImplemented
        return self.priority >= other.priority

priority property

Get the priority of the ListStatus for comparison purposes.

__eq__(other)

Check equality with another ListStatus (not based on priority).

Source code in .venv/lib/python3.14/site-packages/anibridge/list/base.py
def __eq__(self, other: object) -> bool:
    """Check equality with another ListStatus (not based on priority)."""
    if not isinstance(other, ListStatus):
        return NotImplemented
    return self.value == other.value

__ge__(other)

Check if this ListStatus has higher or equal priority than another.

Source code in .venv/lib/python3.14/site-packages/anibridge/list/base.py
def __ge__(self, other: object) -> bool:
    """Check if this ListStatus has higher or equal priority than another."""
    if not isinstance(other, ListStatus):
        return NotImplemented
    return self.priority >= other.priority

__gt__(other)

Check if this ListStatus has higher priority than another.

Source code in .venv/lib/python3.14/site-packages/anibridge/list/base.py
def __gt__(self, other: object) -> bool:
    """Check if this ListStatus has higher priority than another."""
    if not isinstance(other, ListStatus):
        return NotImplemented
    return self.priority > other.priority

__le__(other)

Check if this ListStatus has lower or equal priority than another.

Source code in .venv/lib/python3.14/site-packages/anibridge/list/base.py
def __le__(self, other: object) -> bool:
    """Check if this ListStatus has lower or equal priority than another."""
    if not isinstance(other, ListStatus):
        return NotImplemented
    return self.priority <= other.priority

__lt__(other)

Check if this ListStatus has lower priority than another.

Source code in .venv/lib/python3.14/site-packages/anibridge/list/base.py
def __lt__(self, other: object) -> bool:
    """Check if this ListStatus has lower priority than another."""
    if not isinstance(other, ListStatus):
        return NotImplemented
    return self.priority < other.priority

ListTarget dataclass

Resolved mapping descriptor to a list media key.

Source code in .venv/lib/python3.14/site-packages/anibridge/list/base.py
@dataclass(frozen=True, slots=True)
class ListTarget:
    """Resolved mapping descriptor to a list media key."""

    descriptor: MappingDescriptor
    media_key: str

ListUser dataclass

User information for a list provider.

Source code in .venv/lib/python3.14/site-packages/anibridge/list/base.py
@dataclass(frozen=True, slots=True)
class ListUser:
    """User information for a list provider."""

    key: str
    title: str = field(compare=False)