Metadata-Version: 2.4
Name: resumable-upload
Version: 0.0.4
Summary: A Python implementation of the `TUS resumable upload protocol` for server and client, with zero runtime dependencies.
Author-email: Injae Ryou <injaeryou@gmail.com>
License: MIT
Project-URL: Homepage, https://github.com/sts07142/resumable-upload
Project-URL: Documentation, https://sts07142.github.io/resumable-upload/
Project-URL: Repository, https://github.com/sts07142/resumable-upload
Project-URL: Issues, https://github.com/sts07142/resumable-upload/issues
Project-URL: Changelog, https://github.com/sts07142/resumable-upload/releases
Keywords: tus,upload,resumable,file-upload,server,client,http
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Developers
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Classifier: Topic :: Internet :: WWW/HTTP :: HTTP Servers
Classifier: Topic :: System :: Networking
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.9
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Programming Language :: Python :: 3.14
Classifier: Programming Language :: Python :: 3 :: Only
Requires-Python: >=3.9
Description-Content-Type: text/markdown
License-File: LICENSE
Provides-Extra: dev
Requires-Dist: pytest>=7.0.0; extra == "dev"
Requires-Dist: pytest-cov>=4.0.0; extra == "dev"
Requires-Dist: ruff>=0.1.0; extra == "dev"
Requires-Dist: pre-commit>=3.0.0; extra == "dev"
Requires-Dist: tox>=4.0.0; extra == "dev"
Provides-Extra: test
Requires-Dist: pytest>=7.0.0; extra == "test"
Requires-Dist: pytest-cov>=4.0.0; extra == "test"
Requires-Dist: flask>=2.0.0; extra == "test"
Requires-Dist: fastapi>=0.100.0; extra == "test"
Requires-Dist: uvicorn>=0.38.0; extra == "test"
Requires-Dist: httpx>=0.24.0; extra == "test"
Requires-Dist: django>=3.2.0; extra == "test"
Provides-Extra: s3
Requires-Dist: boto3>=1.26.0; extra == "s3"
Provides-Extra: gcs
Requires-Dist: google-cloud-storage>=2.0.0; extra == "gcs"
Provides-Extra: azure
Requires-Dist: azure-storage-blob>=12.0.0; extra == "azure"
Provides-Extra: all-storage
Requires-Dist: boto3>=1.26.0; extra == "all-storage"
Requires-Dist: google-cloud-storage>=2.0.0; extra == "all-storage"
Requires-Dist: azure-storage-blob>=12.0.0; extra == "all-storage"
Provides-Extra: docs
Requires-Dist: mkdocs-material<10,>=9.5; extra == "docs"
Requires-Dist: mkdocs<2,>=1.6; extra == "docs"
Requires-Dist: mkdocs-git-revision-date-localized-plugin>=1.2; extra == "docs"
Dynamic: license-file

# Resumable Upload

[![Python Version](https://img.shields.io/pypi/pyversions/resumable-upload.svg)](https://pypi.org/project/resumable-upload/)
[![PyPI Version](https://img.shields.io/pypi/v/resumable-upload.svg)](https://pypi.org/project/resumable-upload/)
[![License](https://img.shields.io/pypi/l/resumable-upload.svg)](https://github.com/sts07142/resumable-upload/blob/main/LICENSE)

**English** | [한국어](README.ko.md)

A Python implementation of the [TUS resumable upload protocol](https://tus.io/) 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)

```bash
# 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

```bash
pip install resumable-upload
```

## 🚀 Quick Start

### Basic Server

```python
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

```python
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](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 with `stop_event`
- Exception handling
- Web framework integration (Flask, FastAPI, Django)

## 📚 API Reference

Full API documentation is available in **[docs/api-reference.md](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](https://tus.io/protocols/resumable-upload.html). Full compliance details: **[TUS_COMPLIANCE.md](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-Checksum` uses **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)

```bash
# 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](README.md)
- **한국어 (Korean)**: [README.ko.md](README.ko.md)
- **Advanced Usage**: [docs/advanced-usage.md](docs/advanced-usage.md)
- **Full API Reference**: [docs/api-reference.md](docs/api-reference.md)
- **TUS Protocol Compliance**: [TUS_COMPLIANCE.md](TUS_COMPLIANCE.md)

## 🤝 Contributing

Contributions are welcome! Please check out the [Contributing Guide](.github/CONTRIBUTING.md) for guidelines.

## 📄 License

MIT License - see [LICENSE](LICENSE) file for details.

## 🙏 Acknowledgments

This library is inspired by the official [TUS Python client](https://github.com/tus/tus-py-client) and implements the [TUS resumable upload protocol](https://tus.io/).

## 📞 Support

- 📫 Issues: [GitHub Issues](https://github.com/sts07142/resumable-upload/issues)
- 📖 Documentation: [sts07142.github.io/resumable-upload](https://sts07142.github.io/resumable-upload/)
- 🌟 Star us on GitHub!
