1 Public API Reference
Hirad edited this page 2026-08-14 09:18:17 +03:30

Public API Reference

This page documents the supported imports re-exported by syncfm_core, plus the public structural protocols in syncfm_core.protocols. All models are frozen, slotted dataclasses unless noted.

Factories and services

create_sync_service(database_path, retry_policy=None, progress_callback=None) -> SyncService

Initializes the SQLite schema and returns a fully wired synchronization service.

SyncService

Method Result Notes
sync(source, target, request, *, source_profile=None, target_profile=None) SyncResult Starts and executes a new session; profile names are all-or-none
resume(session_id, source, target, *, source_profile=None, target_profile=None) SyncResult Recovers and continues persisted work
get_pending_sessions() list[SyncSession] Returns sessions whose phase is not completed
get_session(session_id) SyncSession Raises SessionNotFoundError if absent
discard(session_id) None Deletes persisted session state; raises SessionNotFoundError if absent

NetworkFactory.create(config) -> MusicNetwork

Creates a Last.fm, Libre.fm, or GNU.fm pylast adapter. It validates required credentials, GNU.fm hostname, and proxy syntax.

create_profile_service(config_path=None, *, keyring_service="syncfm") -> ProfileService

Creates a TOML-backed profile service using the OS keyring for keyring profiles. With no path it uses default_profile_path().

ProfileService

Method Result Notes
get(name) NetworkProfile Non-secret profile; raises when absent
list() list[NetworkProfile] Sorted by name
save(profile_input, *, replace=False) NetworkProfile Creates or replaces a profile
remove(name) None Removes config and associated keyring secret
resolve(name) NetworkConfig Combines config and secrets for NetworkFactory

default_profile_path() returns the platform-appropriate user config file.

Network and profile models

NetworkType

String enum values: LASTFM = "lastfm", LIBREFM = "librefm", and GNUFM = "gnufm".

NetworkConfig

NetworkConfig(
    type: NetworkType,
    username: str,
    password: str,
    api_key: str,
    api_secret: str,
    session_key: str | None = None,
    hostname: str | None = None,
    proxy: str | None = None,
)

At least one of non-empty password or session_key is required by NetworkFactory.

SecretStorage

String enum values: KEYRING = "keyring" and FILE = "file".

ProfileInput

Fields: name, type, username, api_key, api_secret, optional password, session_key, hostname, proxy, and secret_storage (default keyring). Secret fields are excluded from repr.

NetworkProfile

Represents persisted profile information. Fields are name, type, username, api_key, optional hostname, optional proxy, secret_storage, and optional internal inline_secrets. Prefer ProfileService.resolve() when creating a network.

Synchronization models

SyncRequest

Optional start_timestamp and end_timestamp. The resolver supplies omitted values.

SyncRange

Resolved integer start_timestamp and end_timestamp.

Scrobble

Fields: artist: str, title: str, timestamp: int, album: str | None = None, and metadata: TrackMetadata | None = None.

TrackMetadata

Optional mbid: str and duration_ms: int.

RetryPolicy

max_attempts: int = 3 and delay_seconds: float = 5.0. Attempts must be positive and delay non-negative.

SyncPhase

String enum values: created, fetching, comparing, enriching, syncing, completed, and failed.

SyncSession

Fields: id, source_name, target_name, start_timestamp, end_timestamp, phase, optional source_profile, and optional target_profile.

Session IDs are eight characters generated from an unambiguous lowercase alphabet.

SyncProgress

Fields: phase, completed, total, optional current_scrobble, and current_scrobble_completed. Counts are non-negative and completed cannot exceed total. ProgressCallback is Callable[[SyncProgress], None].

SyncResult

Fields: session_id, source_count, target_count, queued_count, synced_count, and failed_count. The result is built before successful-session state is deleted.

Protocols

Import these from syncfm_core.protocols:

  • ScrobbleReader: get_scrobbles(...) and get_latest_scrobble_timestamp()
  • MetadataProvider: get_track_metadata(artist, title)
  • ScrobbleWriter: submit_scrobble(scrobble)
  • MusicNetwork: combines all three and a name property
  • SyncSessionRepository, ScrobbleSnapshotRepository, and SyncQueueRepository: persistence injection points

Python runtime structural conformance is used; implementations need not inherit the protocols.

Exception hierarchy

SyncFMCoreError
├── ConfigurationError
│   ├── ProfileNotFoundError
│   ├── ProfileAlreadyExistsError
│   └── SecretStorageError
├── NetworkError
│   ├── AuthenticationError
│   ├── NetworkConnectionError
│   ├── InvalidNetworkResponseError
│   └── RetryExhaustedError
├── PersistenceError
└── SynchronizationError
    ├── InvalidSyncRangeError
    ├── MissingStartTimestampError
    └── SessionNotFoundError

Catch SyncFMCoreError at an application boundary, or a narrower branch when recovery differs. ValueError can also arise directly from invalid RetryPolicy or SyncProgress construction.

Lower-level exports

syncfm_core.models additionally exports SyncQueueItem and SyncStatus. Lower-level services and concrete SQLite repositories live in subpackages. They are useful for custom composition but are not re-exported from the package root; pin a revision if depending on these internals.