Uploads

Uploads adapt automatically, so most applications need only their paths. When Files.com allows parallel parts, the SDK adjusts how many it sends based on the connection, within your concurrency, memory and connection limits. Server-required serial uploads and unspooled unknown-length streams remain serial.

upload_file() uploads a local file; upload_stream() uploads a binary stream. Both return the File created. A file uses a separate handle for each part; a stream is read forward once. Keep the source unchanged until the call finishes.

cancel_token, request_timeout and deadline cover the whole upload, including completion. See Cancellation and Deadlines.

Uploading a File

import files_sdk

try:
  with files_sdk.Client(api_key="YOUR_API_KEY") as client:
    file = client.file.upload_file("backups/big.iso", "archive/big.iso", params={"mkdir_parents": True})
    print(file.path, file.size)
except files_sdk.error.NotAuthenticatedError as err:
  print(f"Authentication Error Occurred ({type(err).__name__}):", err)
except files_sdk.error.Error as err:
  print(f"Unknown Error Occurred ({type(err).__name__}):", err)

Streams

Streams are read from their current position, never sought, and left open after the uploaded bytes. Short reads are accumulated; only an empty read means the end. Use a blocking binary stream.

ChoiceBehavior
upload_stream(stream, destination, size)Reads exactly size bytes; an early end fails without completing.
Omit sizeSends parts serially until the stream ends. Eligible part sizes can grow within server limits.
spool_limitCopies the full unknown-length stream to a bounded temporary file first, enabling parallel file-style upload. An oversized stream fails before any upload is sent.
spool_directoryChooses the spool folder instead of the system temporary folder. The SDK removes its spool afterward.

After a full part, one byte of look-ahead determines whether another is needed. An exact boundary can complete with the maximum allowed parts; excess data raises InvalidRequestError without completing. Text streams and a nonblocking read() returning None also fail before completion.

Uploading Part of a Stream

import files_sdk

try:
  with open("report.csv", "rb") as source:
    source.seek(128)
    files_sdk.upload_stream(source, "reports/report.csv", 4096)
except files_sdk.error.NotAuthenticatedError as err:
  print(f"Authentication Error Occurred ({type(err).__name__}):", err)
except files_sdk.error.Error as err:
  print(f"Unknown Error Occurred ({type(err).__name__}):", err)

Progress

Pass a progress function. It receives files_sdk.UploadProgress on the calling thread, at most four times a second and once more after all parts arrive. If it raises, the upload stops its active parts and propagates the exception. All bytes accepted does not establish upload completion; wait for the upload call to return.

FieldMeaning
bytes_committedBytes in accepted parts, counted once.
bytes_sentNetwork bytes, including retries.
bytes_per_secondRecent committed-byte rate.
total_bytesUpload size.

Following Upload Progress

def report(progress):
  print(f"{progress.bytes_committed} of {progress.total_bytes} bytes")

file = files_sdk.upload_file("video.mp4", "media/video.mp4", progress=report)

Failures

Parts retry with identical bytes under the transfer retry rules, only when Files.com allows retries. Accepted parts are not sent again. Expiring addresses are renewed for the same part before use; addresses refused as expired can be renewed up to twice. Ordinary refusals, including a 403 without an expiry reason, fail. The SDK recognizes supplied expiry and supported AWS, Files.com, Google and Azure signing fields.

A permanent part failure stops the other parts, waits for them and raises the original error without completing. For local files, size and modification time are checked around each read and before completion, plus status-change time off Windows. A changed file raises InvalidRequestError instead of completing mixed content.

The final completion request is not replayed once it may have reached Files.com. A lost or error response can leave remote_outcome_unknown set even though the file completed. Check the remote outcome before starting another upload; Pausing and Resuming covers checkpoint recovery.

Adapting to the Connection

Default automatic mode adds parts when measurements show an improvement and backs off after failures or backpressure. HTTP 429, 503 or 504 pauses all new attempts, retries included, through Retry-After (at most 60 seconds at a time). A retry or URL-renewal wait releases its controller place. Cancelled attempts and failures predating the last backoff do not trigger another backoff. Measurements cover the request through response headers, not waiting time.

max_concurrency, from 1 to 1024, caps either startup. Explicit limiter bounds and server-required serial behavior still apply. UploadTuning can be passed per transfer as tuning, or per client as upload_tuning.

Startup and Explicit Tuning

Eligible Amazon S3 uploads use the SDK's scaled policy unless you provide concurrency tuning:

ChoiceStarting behavior
UploadStartup.DEFAULTProbes from one part. A measured 96 MiB/s window can promote to the policy's initial target.
UploadStartup.AGGRESSIVEStarts at the policy's initial target on a connection you already know is fast.
UploadTuning(adaptive=False)Fixed max_concurrency, or 4 when not specified.
Explicit concurrency settingsUses the configurable controller's supplied start/growth/backoff.

The scaled policy grows toward 150 parts, and can target up to 1024 after a qualifying fast link has carried 64 GiB. Only busy measurement windows are judged. Both startups adapt the same way and can reach the same ceiling; neither overrides caps or changes other destination profiles. Startup cannot be combined with static mode or explicit concurrency settings. These policy settings are not a throughput guarantee.

Part Sizes

Where Files.com permits client-selected sizes, the SDK fits them to the file and concurrency within granted size and part-count limits. Scaled-policy files try larger unread parts at a stable concurrency share and keep them only for a 10% throughput gain. Otherwise server-planned sizes apply. If Files.com withdraws or narrows the grant, the upload stops before sending further parts.

Optional Upload Tuning

import files_sdk

try:
  files_sdk.upload_file("backups/big.iso", "archive/big.iso", max_concurrency=16)
  
  fast_link = files_sdk.UploadTuning(startup=files_sdk.UploadStartup.AGGRESSIVE)
  files_sdk.upload_file("video.mp4", "media/video.mp4", tuning=fast_link)
  
  steady = files_sdk.UploadTuning(adaptive=False)
  files_sdk.upload_file("nightly.tar", "backups/nightly.tar", max_concurrency=6, tuning=steady)
except files_sdk.error.NotAuthenticatedError as err:
  print(f"Authentication Error Occurred ({type(err).__name__}):", err)
except files_sdk.error.Error as err:
  print(f"Unknown Error Occurred ({type(err).__name__}):", err)

Memory and Connections

TransferLimiter shares the budget across clients or transfers without sharing credentials or their learned concurrency targets. Waiting uploads are admitted in request order; a directory job shares learning separately.

ResourceAccounting
Stream partRetained whole until accepted, so retries resend identical bytes. A part holds what is left of the stream, up to the part size Files.com gives, and at most 5 GiB: a stream part of more fails the upload, before it is read when size shows that. upload_file() and spool_limit send parts from a file instead.
Local-file partCopy buffer of at most 64 KiB. Small parts, or parts of up to 5 GiB under DEBUG logging, are read whole before sending; DEBUG logs content.
Client's implicit limiter1024 parts and 128 MiB, shared with downloads. Module-level functions share one implicit limiter.
Explicit TransferLimiter()Defaults to 32 parts and 256 MiB; the SDK does not raise supplied limits.
SDK buffer reservation larger than max_bytesWaits until no other reservation holds buffer room, then is admitted alone.

The budget covers SDK part buffers, not your stream buffers or HTTP-library memory. Bounded stream read-ahead can prepare a few parts while active parts are busy.

Sharing a Transfer Budget

import files_sdk

limiter = files_sdk.TransferLimiter(max_parts=6, max_bytes=128 * 1024 * 1024)
first = files_sdk.Client(api_key="FIRST_KEY", transfer_limiter=limiter)
second = files_sdk.Client(api_key="SECOND_KEY", transfer_limiter=limiter)

Writing Remote Files

files_sdk.open(path, "wb") uploads one part at a time as it fills, and the remainder on close; it holds at most one part, up to 5 GiB, and a write past that fails the upload. Text mode "w" encodes UTF-8. flush() cannot send a short middle part early. A failed write or close sends nothing further. See Remote Files and Folders, including why leaving a with block with an exception can still complete the bytes already written.

Diagnostics

Set UploadTuning.observer to receive UploadObservation on the uploading thread. It covers planning/fallbacks, controller and part-size decisions, limiter/read-ahead/cooldown waits, samples at most four times a second, and a final outcome/settings/attempts record with SDK and Python versions.

Unavailable measurements are None, not zero: an unknown-size serial stream reports waits and its active part, but no runway, controller decisions or throughput samples. Observations contain only numbers and names, never paths, URLs, headers or credentials, and are not collected without an observer. Observer exceptions stop the upload except in the final notification, where they are logged.