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
- SyncVerification
- 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. The standard verification service checks fresh target history up to three times with a two-second delay; changing those verification settings requires direct SyncService composition.
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".
The display_name property returns "Last.fm", "Libref.fm", or "GNU.fm", respectively. "Libref.fm" is the spelling currently returned by version 0.2.1.
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, failed_count, and verification: SyncVerification. The count fields describe the stored initial snapshots and queue. The result is built before completed-session state is deleted.
SyncVerification
Fields: start_timestamp, end_timestamp, source_count, target_count, missing_on_source: tuple[Scrobble, ...], and missing_on_target: tuple[Scrobble, ...]. These counts and differences come from fresh network reads after submission rather than the stored initial snapshots.
source_fully_synced is true when missing_on_target is empty. histories_match is stricter and is true only when neither history has occurrences missing from the other. Verification preserves duplicate occurrences when comparing exact (artist, title, timestamp) identities.
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, including VerificationService, 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.