Public API

A synchronous client for the LocalSend v2 protocol.

Use Client to discover and register peers, send and receive files, and share files with a browser.

class localsend.Client(name: str | None = None, *, download_directory: Path | str | None = None, on_receive_request: Callable[[IncomingTransfer], bool | Collection[str] | None] | None = None, on_received: Callable[[ReceivedFile], None] | None = None, on_receive_failed: Callable[[ReceiveFailure], None] | None = None, on_share_request: Callable[[ShareRequest], bool] | None = None, port: int = 53317, advertise_host: str = '127.0.0.1', device_model: str | None = None, device_type: str | None = 'desktop', pin: str | None = None, session_timeout: float = 300.0, identity_path: Path | str | None = None, discovery_interfaces: Iterable[str] | None = None, http_discovery_networks: Iterable[IPv4Network] = ())

Discover LocalSend peers and transfer files synchronously.

Omit name to generate an English adjective-and-noun alias. device_model and device_type identify this client to peers.

To receive files, set download_directory and provide on_receive_request. It runs on an incoming-request worker and may return False to reject all files, a collection of file IDs to accept a subset, or True/None to accept all files. Concurrent offers may invoke it concurrently. on_received runs serially after each file is saved; callback failures are logged, and close() waits for queued callbacks. on_receive_failed reports accepted files that cannot be saved completely.

on_share_request authorizes browser downloads and runs synchronously on an incoming-request worker. Return True to authorize the browser-bound session. Set advertise_host to this machine’s LAN address before sharing files with another device.

discovery_interfaces selects IPv4 addresses for multicast; otherwise locally resolved addresses are used. http_discovery_networks enables a bounded private-IPv4 scan when multicast is unavailable. Interfaces are selected by start(); after an interface change or multicast-listener error, call close() and start().

The client keeps a mutual-TLS identity at $XDG_STATE_HOME/localsend-python/identity.pem or ~/.local/state/localsend-python/identity.pem. Set identity_path to retain it elsewhere or rotate it.

property devices: tuple[Device, ...]

Return LocalSend devices found through discovery or registration.

register(peer: Device) Device

Register with peer and return its confirmed identity.

Uses the peer’s advertised HTTP or HTTPS protocol and pins an HTTPS certificate to its discovered fingerprint. The confirmed peer is added to devices. Network and invalid-response failures raise RuntimeError.

info(peer: Device) DeviceInfo

Return diagnostic identity information from peer.

Pins an HTTPS certificate to the peer’s discovered fingerprint. Network and invalid-response failures raise RuntimeError.

start() None

Start the HTTP server and multicast discovery socket.

Concurrent calls share one startup transition. A client closed previously is reopened before its listeners start.

close() None

Stop the HTTP server and multicast discovery socket.

This serializes with start(); it is safe to call repeatedly.

prepare_upload(peer: Device, files: Iterable[Path | str], *, pin: str | None = None) UploadSession | None

Offer files to peer and return its accepted upload session.

Call UploadSession.upload() to send accepted files or UploadSession.cancel() to withdraw the offer. Returns None if files is empty or the peer accepts no files; an empty iterable makes no network request. A peer may accept only a subset of the offer.

Pins an HTTPS certificate to the peer’s discovered fingerprint. Missing or invalid PINs raise PinRequiredError; a rejected offer raises UploadRejectedError; an active peer transfer raises UploadSessionBlockedError; and network failures raise RuntimeError. Connection establishment is limited to two seconds, then the receiver has five minutes to approve the offer.

send_files(peer: Device, files: Iterable[Path | str], *, pin: str | None = None) tuple[Path, ...]

Send files to peer and return the uploaded paths.

Equivalent to prepare_upload() followed by UploadSession.upload(). A peer may partially accept an offer, so the result contains only accepted, successfully uploaded paths. An empty iterable returns () without a network request.

If the client is started and the peer cancels an active upload, UploadCancelledError is raised. Network failures raise RuntimeError.

share(files: Iterable[Path | str]) str

Publish files at LocalSend’s browser-download endpoint.

Start the client first so the returned URL is reachable. Set advertise_host to this machine’s LAN address before sharing with another device.

class localsend.Device(alias: str, fingerprint: str, host: str | None = None, port: int = 53317, protocol: str = 'http')

A LocalSend device visible to an incoming transfer.

class localsend.DeviceInfo(alias: str, version: str, fingerprint: str, device_model: str | None, device_type: str | None, download: bool)

Diagnostic identity information reported by a LocalSend peer.

class localsend.IncomingFile(id: str, name: str, size: int, media_type: str)

Metadata for one file offered by a remote sender.

class localsend.IncomingTransfer(sender: Device, files: tuple[IncomingFile, ...])

An incoming transfer offered for local authorization.

class localsend.ReceiveFailure(sender: Device, file: IncomingFile, received_size: int, reason: Literal['size_mismatch', 'write_failed'])

An incoming file that could not be saved completely.

class localsend.ReceivedFile(sender: Device, file: IncomingFile, path: Path)

A file saved after an incoming transfer was authorized.

class localsend.ShareRequest(host: str | None, files: tuple[Path, ...])

A browser asking to download the files in the current share.

exception localsend.PinRequiredError

Raised when a peer requires a missing or different upload PIN.

exception localsend.UploadCancelledError

Raised when a peer cancels an active outbound upload.

exception localsend.UploadRejectedError

Raised when a peer rejects an offered upload before file transfer.

class localsend.UploadSession

An accepted outbound upload that can be sent or cancelled once.

property accepted_files: tuple[Path, ...]

Return the offered paths accepted by the receiving peer.

cancel() None

Cancel this upload session at the receiving peer.

upload() tuple[Path, ...]

Upload the accepted files to the receiving peer.

exception localsend.UploadSessionBlockedError

Raised when a peer has another active upload session.