A Python implementation of the `TUS resumable upload protocol` for server and client, with zero runtime dependencies.
Project description
Resumable Upload
English | 한국어
A Python implementation of the TUS resumable upload protocol v1.0.0 for server and client, with zero runtime dependencies.
✨ Features
- 🚀 Zero Dependencies: Built using Python standard library only (no external dependencies for core functionality)
- 📦 Server & Client: Complete implementation of both sides
- 🔄 Resume Capability: Automatically resume interrupted uploads
- ✅ Data Integrity: Optional SHA1 checksum verification
- 🔁 Retry Logic: Built-in automatic retry with exponential backoff
- 📊 Progress Tracking: Detailed upload progress callbacks with stats
- 🌐 Web Framework Support: Integration examples for Flask, FastAPI, and Django
- 🐍 Python 3.9+: Supports Python 3.9 through 3.14
- 🏪 Storage Backend: SQLite-based storage (extensible to other backends)
- 🔐 TLS Support: Certificate verification control and mTLS authentication
- 📝 URL Storage: Persist upload URLs across sessions
- 🎯 TUS Protocol Compliant: Implements TUS v1.0.0 core protocol with creation, termination, and checksum extensions
📦 Installation
Using uv (Recommended)
# Install uv if you haven't already
curl -LsSf https://astral.sh/uv/install.sh | sh
# Install the package
uv pip install resumable-upload
Using pip
pip install resumable-upload
🚀 Quick Start
Basic Server
from http.server import HTTPServer
from resumable_upload import TusServer, TusHTTPRequestHandler, SQLiteStorage
# Create storage backend
storage = SQLiteStorage(db_path="uploads.db", upload_dir="uploads")
# Create TUS server
tus_server = TusServer(storage=storage, base_path="/files")
# Create HTTP handler
class Handler(TusHTTPRequestHandler):
pass
Handler.tus_server = tus_server
# Start server
server = HTTPServer(("0.0.0.0", 8080), Handler)
print("Server running on http://localhost:8080")
server.serve_forever()
Basic Client
from resumable_upload import TusClient
# Create client
client = TusClient("http://localhost:8080/files")
# Upload file with progress callback
from resumable_upload import UploadStats
def progress(stats: UploadStats):
print(f"Progress: {stats.progress_percent:.1f}% | "
f"{stats.uploaded_bytes}/{stats.total_bytes} bytes | "
f"Speed: {stats.upload_speed_mbps:.2f} MB/s")
upload_url = client.upload_file(
"large_file.bin",
metadata={"filename": "large_file.bin"},
progress_callback=progress
)
print(f"Upload complete: {upload_url}")
🔧 Advanced Usage
For detailed guides see docs/advanced-usage.md:
- Automatic retry with exponential backoff
- Resume interrupted uploads (in-session and cross-session)
- Partial uploads with
stop_at - Low-level chunk control via
Uploader+ cancellation withstop_event - Exception handling
- Web framework integration (Flask, FastAPI, Django)
📚 API Reference
Full API documentation is available in docs/api-reference.md.
Quick Reference
| Class | Import | Purpose |
|---|---|---|
TusClient |
from resumable_upload import TusClient |
Upload files via TUS protocol |
TusServer |
from resumable_upload import TusServer |
Serve TUS uploads (framework-agnostic) |
TusHTTPRequestHandler |
from resumable_upload import TusHTTPRequestHandler |
Handler for Python's built-in HTTPServer |
SQLiteStorage |
from resumable_upload import SQLiteStorage |
SQLite + filesystem storage backend |
FileURLStorage |
from resumable_upload import FileURLStorage |
JSON file-based URL persistence |
Uploader |
from resumable_upload.client.uploader import Uploader |
Low-level chunk-by-chunk control |
Key Parameters
TusClient: url, chunk_size (default 1 MB), checksum (SHA1, default True), max_retries (default 3), retry_delay (default 1.0s, exponential backoff capped at 60s), timeout (default 30s), store_url / url_storage (cross-session resume), verify_tls_cert, headers
TusServer: storage, base_path (default /files), max_size, upload_expiry, cors_allow_origins, request_timeout (default 30s — Slowloris protection)
SQLiteStorage: db_path (default uploads.db), upload_dir (default uploads) — thread-safe via per-upload lock; process-safe via fcntl.flock
FileURLStorage: storage_path (default .tus_urls.json) — thread-safe via threading.Lock; process-safe via fcntl.flock
🔍 TUS Protocol Compliance
This library implements TUS protocol v1.0.0. Full compliance details: TUS_COMPLIANCE.md.
Extensions
| Extension | Status |
|---|---|
| core | ✅ Implemented |
| creation | ✅ Implemented |
| creation-with-upload | ✅ Implemented |
| termination | ✅ Implemented |
| checksum | ✅ Implemented (SHA1) |
| expiration | ✅ Implemented |
| concatenation | ❌ Not implemented |
Note: TUS
Upload-Checksumuses SHA1 as required by the spec. The internal client-side fingerprint for cross-session resume uses SHA-256 and is not part of the TUS protocol.
🧪 Testing
Using uv (Recommended)
# Install uv if you haven't already
curl -LsSf https://astral.sh/uv/install.sh | sh
# Create virtual environment and install dependencies
uv venv
source .venv/bin/activate # On Windows: .venv\Scripts\activate
# Install all dependencies (dev and test)
make install
# Run minimal tests (excluding web frameworks)
make test-minimal
# Run all tests (including web frameworks)
make test
# Or use Makefile for convenience
make lint # Run linting
make format # Format code
make test-minimal # Run minimal tests
make test # Run all tests
make test-all-versions # Test on all Python versions (3.9-3.14) - requires tox
make ci # Run full CI checks (lint + format + test)
📖 Documentation
- English: README.md
- 한국어 (Korean): README.ko.md
- Advanced Usage: docs/advanced-usage.md
- Full API Reference: docs/api-reference.md
- TUS Protocol Compliance: TUS_COMPLIANCE.md
🤝 Contributing
Contributions are welcome! Please check out the Contributing Guide for guidelines.
📄 License
MIT License - see LICENSE file for details.
🙏 Acknowledgments
This library is inspired by the official TUS Python client and implements the TUS resumable upload protocol.
📞 Support
- 📫 Issues: GitHub Issues
- 📖 Documentation: sts07142.github.io/resumable-upload
- 🌟 Star us on GitHub!
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file resumable_upload-0.0.3.tar.gz.
File metadata
- Download URL: resumable_upload-0.0.3.tar.gz
- Upload date:
- Size: 34.8 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
3ea4bb7a094694f50c7c9830313da8f0f12b1e06705bb47e57395107ee2ae2c8
|
|
| MD5 |
f73cdaab3baeec2687f29ea60828a09c
|
|
| BLAKE2b-256 |
8e1305fa9fcf053172e8c1de185aa35bdabf561443f4fa1021f5b4aade36fa83
|
Provenance
The following attestation bundles were made for resumable_upload-0.0.3.tar.gz:
Publisher:
publish.yml on sts07142/resumable-upload
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
resumable_upload-0.0.3.tar.gz -
Subject digest:
3ea4bb7a094694f50c7c9830313da8f0f12b1e06705bb47e57395107ee2ae2c8 - Sigstore transparency entry: 1004742980
- Sigstore integration time:
-
Permalink:
sts07142/resumable-upload@d636e1dae4b884994dc82c4f217255e42391f957 -
Branch / Tag:
refs/tags/v0.0.3 - Owner: https://github.com/sts07142
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@d636e1dae4b884994dc82c4f217255e42391f957 -
Trigger Event:
release
-
Statement type:
File details
Details for the file resumable_upload-0.0.3-py3-none-any.whl.
File metadata
- Download URL: resumable_upload-0.0.3-py3-none-any.whl
- Upload date:
- Size: 26.9 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
aae459f4ab10e2dadde6faef29562b39ed8f10b56c75508c91014a5a09fdbcd1
|
|
| MD5 |
30dffb86b814f0cdde4238c1dd8e2131
|
|
| BLAKE2b-256 |
762d5d97ef49b25f5a6ef9f64ab439d4647585792f7d0f532e445fe1f65b9d91
|
Provenance
The following attestation bundles were made for resumable_upload-0.0.3-py3-none-any.whl:
Publisher:
publish.yml on sts07142/resumable-upload
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
resumable_upload-0.0.3-py3-none-any.whl -
Subject digest:
aae459f4ab10e2dadde6faef29562b39ed8f10b56c75508c91014a5a09fdbcd1 - Sigstore transparency entry: 1004742981
- Sigstore integration time:
-
Permalink:
sts07142/resumable-upload@d636e1dae4b884994dc82c4f217255e42391f957 -
Branch / Tag:
refs/tags/v0.0.3 - Owner: https://github.com/sts07142
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@d636e1dae4b884994dc82c4f217255e42391f957 -
Trigger Event:
release
-
Statement type: