Table of contents
- Public API Reference
- Factories and services
- create_sync_service(database_path, retry_policy=None, progress_callback=None) -> SyncService
- SyncService
- NetworkFactory.create(config) -> MusicNetwork
- create_profile_service(config_path=None, *, keyring_service="syncfm") -> ProfileService
- ProfileService
- Network and profile models
- Synchronization models
- SyncRequest
- SyncRange
- Scrobble
- TrackMetadata
- RetryPolicy
- SyncPhase
- SyncSession
- SyncProgress
- SyncResult
- Protocols
- Exception hierarchy
- Lower-level exports
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(...)andget_latest_scrobble_timestamp()MetadataProvider:get_track_metadata(artist, title)ScrobbleWriter:submit_scrobble(scrobble)MusicNetwork: combines all three and anamepropertySyncSessionRepository,ScrobbleSnapshotRepository, andSyncQueueRepository: 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.