Low-Level Uploader¶
Uploader gives you chunk-by-chunk control over the upload process.
Obtain one via TusClient.create_uploader() or instantiate directly.
Chunk-by-Chunk Upload¶
uploader = client.create_uploader("large_file.bin")
while uploader.upload_chunk():
stats = uploader.stats
print(f"Uploaded {stats.uploaded_bytes} / {stats.total_bytes} bytes")
uploader.close()
upload_chunk() returns True while there are more chunks to send, False when the upload is complete.
Cancellation via stop_event¶
Pass a threading.Event to cancel an upload cleanly from another thread:
import threading
from resumable_upload.client.uploader import Uploader
stop = threading.Event()
uploader = Uploader(
url=upload_url,
file_path="large_file.bin",
stop_event=stop,
)
# From another thread:
stop.set() # Interrupts the retry wait and raises TusUploadFailed("cancelled")
The event is checked during retry waits, so cancellation is responsive even on slow connections.
Connection Reuse¶
An Uploader keeps one HTTP connection for its HEAD and every PATCH, so a chunked upload pays the TCP (and TLS) handshake once instead of per chunk. This needs nothing from you and degrades safely:
- an HTTP/1.0 server, or one answering
Connection: close, simply makes every request reconnect; - a kept-alive socket the server has since dropped (idle timeout, restart) is reopened once, transparently; a chunk the server had already applied surfaces as
409and goes through the offset re-sync below; a timeout is not resent that way — it fails the attempt and goes throughmax_retrieslike any other error; - an environment proxy (
HTTP_PROXY/HTTPS_PROXY, honouringNO_PROXY) keeps going throughurllib, which knows how to use it; - a
3xxis an error (TusCommunicationErroron the offsetHEAD,TusUploadFailedonPATCH), never a silent success — the uploader does not follow redirects, so pass the final URL; - requests carry
urllib's defaultUser-Agent(Python-urllib/3.x) unlessheaderssets one.
close() releases the connection along with the file handle.
409 Conflict Auto-Recovery¶
When the server returns 409 Conflict (offset mismatch), the uploader automatically:
- Sends a HEAD request to fetch the current server offset
- Seeks the local file to that offset
- Retries the chunk from the correct position
This handles cases where a previous chunk was partially accepted by the server.