Downloads
download_file() saves a remote file to a local path; download_stream() writes it into a binary stream.
Both return the downloaded File.
The SDK fetches parallel ranges where storage supports them with reliable version checks, and adjusts concurrency on eligible storage. It can fall back to a whole response when needed. Start with the paths; no tuning is required. Temporary failures are retried within a limit, and you can follow the transfer with a progress callback.
cancel_token, request_timeout and deadline cover the operation from obtaining its download URL to the last byte.
See Cancellation and Deadlines.
Local Files
download_file() writes to a private temporary file beside the destination, then puts it in place after the full
response is validated. It replaces an existing destination. If the destination is a symbolic link, a single-file
download replaces the file it points to; directory downloads instead refuse links. Other hard links to a replaced
file keep the old content.
A failure or cancellation before publication leaves the destination unchanged. With a checkpoint, a complete, version-bound private stage can sometimes be kept for recovery; see Pausing and Resuming. A partial whole response starts from the beginning on the next call.
Without local_path, the file is saved under its own name in the current directory. The SDK needs permission to
create a temporary directory beside the destination. Local Access and Publication
describes platform access rules and failures that prevent replacement.
Streams
download_stream(path, stream) writes from the stream's current position, in order, and leaves it open. It never
seeks, truncates or rewinds. A failure can leave partial content in the stream, and already-written bytes are never
written again. Whole-response retries stop once the stream has accepted bytes.
The stream must be blocking. Partial writes are completed before proceeding. A raw stream returning None or 0
from write() raises InvalidParameterError; for other writers, None means all bytes were accepted. Cancellation
stops before the next write, and your stream's exceptions propagate unchanged.
Ranges fetched ahead are buffered within the client's shared TransferLimiter. For a remote file downloaded as
you read it, use files_sdk.open(path, "r") or "rb"; text uses UTF-8. See
Remote Files and Folders.
This example appends to the local file. Choose its open mode deliberately; use download_file() for staged
replacement.
Progress
Pass a function as progress. It receives files_sdk.DownloadProgress on the calling thread, at most four times
a second while bytes arrive, and once more at completion. If it raises, active ranges stop and its exception is
propagated. Mark the operation successful only after the download call returns.
| Field | Meaning |
|---|---|
bytes_committed | Complete range bytes, or bytes accepted by the stream. For whole responses, written bytes reset to zero if the response restarts. |
bytes_received | Network bytes, including retries. |
total_bytes | Size from the bound version or response length. For an encoded whole response, the size is known only at the end. |
pinned_version | Whether the download is protected by one verified version, independently of whether it uses ranges or a whole response. |
Failures
Temporary range failures, short responses and overruns are retried as Retries and Timeouts describes. An overrun fails before excess bytes are written. A failed whole response restarts from byte zero only while the destination can restart; a stream that has taken bytes cannot.
| Situation | Outcome |
|---|---|
| Storage URL expired or expires within a minute | Renewed for the same version, up to twice. Other refusals, including an ordinary 403, fail. |
| Version is gone or changed, including storage HTTP 412 or a changed bound storage tag | A local-file download starts over once with the current version. A stream already holding old-version bytes raises InvalidRequestError. |
| Invalid identity, malformed or encoded range, disallowed redirect, missing required bound storage tag, or web-app response | APIConnectionError before bytes from that invalid response are written. |
| Storage ignores a range | API-identity downloads reject it; qualified storage-bound downloads may fetch the same version whole, as below. |
URLs are used exactly as Files.com supplies them. Expiry checks recognize the supplied expiry and supported signed-URL fields for AWS, Files.com, Google and Azure. Source and destination stream exceptions retain their own type.
Ranges at Once
Version-bound downloads use 8 MiB ranges. Eligible Amazon S3 downloads use the scaled policy: an initial target of 150 ranges, adapting to throughput, failures, throttling and queueing. Downloads have no upload startup choice or warmup. Other storage with a Files.com-provided identity fetches 4 ranges by default. An endpoint's name selects tuning; it does not by itself establish a version.
max_concurrency, from 1 to 1024, caps the target. tuning accepts files_sdk.UploadTuning;
UploadTuning(adaptive=False) keeps max_concurrency ranges (or 4) at once. Custom concurrency settings use the
configurable controller. Upload-only settings such as startup, observer and part-size options are refused.
Each range reserves buffer space first: a 256 KiB copy buffer for a local file, or the whole range for an ordered
stream. Each network attempt holds a controller place and limiter max_parts slot only while active. Retry and
URL-renewal waits release both slots, keep reserved memory, and wait behind cooldowns. HTTP 429, 503 or 504 pauses
new ranges for Retry-After, even if reading the error body fails. Measurements exclude local-file write time.
Adaptive files within download_directory() or download_files() share a controller for that job;
nonadaptive downloads keep independent targets.
Download Identity
Version protection is automatic. There are two supported sources:
| Source | Binding and checks |
|---|---|
| Files.com-provided download identity | with_download_identity supplies a token, exact size and required headers. Each range must match the requested bytes and size. Required If-Match tags must match any returned strong ETag; a missing response tag remains accepted for compatibility. Renewal with expected_download_identity must return the same token and size. |
| Qualified storage response | Without API identity, HTTPS Amazon S3 general-purpose endpoints on the default port can bind from a first valid HTTP 206 range at byte zero: exact unencoded bytes, authoritative size and a strong ETag. Later requests use If-Match, validate every range/size/tag and follow no redirect. Renewed URLs must name the same storage object. |
API-identity requests can follow redirects within their original origin, retaining required headers. Cross-origin redirects fail before sending there. Storage-bound requests follow no redirects. The storage binding's tag, size and address digest are an SDK record and are never sent to Files.com. This is a qualified conditional-range protocol, not a guess from equal ETags, sizes or modification times.
Other storage uses one unbound response. On eligible storage, an initial HTTP 200, 416 or redirect also
falls back to a whole response. A valid first range without a strong tag stays unbound: it can serve as the
whole response if it already contains the entire small file; otherwise the SDK fetches the file whole.
Malformed initial range encoding, byte coverage or length raises APIConnectionError instead of falling back.
Unbound downloads keep no reusable checkpoint. After storage binding, a missing tag fails validation and a
weak or different tag indicates a changed version, handled as described under Failures.
If qualified storage starts ignoring ranges after binding, the SDK stops other ranges, discards their partial
writes and fetches the whole same version with If-Match. pinned_version remains true. A stream that already
accepted bytes fails instead. A partial whole response restarts; it is not continued mid-response. A complete bound
private local stage may be reused only after checkpoint sync/save and the same identity, privacy, exact-size and
version checks; see Pausing and Resuming.
An identity grants no permissions and is not logged at INFO or above. Checkpoints contain the token/size, or the storage tag/size/resource digest, never credentials, headers or signed URLs. Recovery confirms the version before reusing bytes; missing ranges are fetched only where storage still honors Range.
Local Access and Publication
The temporary directory is named .files_sdk- plus 32 hexadecimal digits. Its directory and file are owner-only;
on macOS inherited ACLs are removed before writing. On POSIX systems, operations use the opened destination
directory's descriptors, protecting against other users and links replaced during the download, but not programs
running as you. Windows uses paths without that protection.
The replacement keeps existing file permissions without set-user-ID, set-group-ID or sticky bits. POSIX systems
also preserve its owner and group; macOS/Linux preserve its ACL. Inability to keep that access raises
files_sdk.localfs.AccessNotKept, an OSError, instead of replacing the file. New macOS files receive their parent
folder's inherited ACL at publication; inability to apply it also fails. Windows does not retain a replaced file's
own access-control entries. The destination directory's permissions are unchanged.