Metadata-Version: 2.3
Name: upyloadthing
Version: 0.1.1
Summary: Python client for the uploadthing API
License: MIT
Author: Fabrice Armisen
Author-email: farmisen@gmail.com
Requires-Python: >=3.12
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Requires-Dist: inflection (>=0.5.1,<0.6.0)
Requires-Dist: pydantic (>=2.10.6,<3.0.0)
Requires-Dist: requests (>=2.32.3,<3.0.0)
Requires-Dist: requests-toolbelt (>=1.0.0,<2.0.0)
Requires-Dist: setuptools (>=75.8.0,<76.0.0)
Requires-Dist: sqids (>=0.5.1,<0.6.0)
Description-Content-Type: text/markdown

# Upyloadthing

[![Build Status](https://github.com/farmisen/upyloadthing/workflows/CI/badge.svg)](https://github.com/farmisen/upyloadthing/actions)
[![PyPI version](https://badge.fury.io/py/upyloadthing.svg)](https://badge.fury.io/py/upyloadthing)
[![Python Versions](https://img.shields.io/pypi/pyversions/upyloadthing.svg)](https://pypi.org/project/upyloadthing/)

Python client for the [uploadthing](https://docs.uploadthing.com/api-reference/openapi-spec) API - The easiest way to add file uploads to your Python application.

## Installation

```bash
pip install upyloadthing
```

## Quick Start

```python
from upyloadthing import UTApi, UTApiOptions

# Initialize with token
api = UTApi(UTApiOptions(token="your-token"))

# Upload a file
with open("example.png", "rb") as f:
    result = api.upload_files(f)
    print(f"File uploaded: {result.url}")
```

## Environment Variables

The SDK can be configured using environment variables:

- `UPLOADTHING_TOKEN` - Your uploadthing API token (required if not passed to UTApiOptions)
- `UPLOADTHING_REGION` - Preferred upload region (optional, defaults to first available region found in the decoded token)

## Examples

### Upload Multiple Files

```python
files = [
    open("image1.jpg", "rb"),
    open("image2.jpg", "rb")
]
results = api.upload_files(files)
for result in results:
    print(f"Uploaded: {result.url}")
```

### Delete Files

```python
# Delete by file key
response = api.delete_files("file_key_123")

# Delete multiple files
response = api.delete_files(["key1", "key2"])

# Delete by custom ID
response = api.delete_files("custom_123", key_type="custom_id")
```

### List Files

```python
# Get first 10 files
files = api.list_files(limit=10)
for file in files.files:
    print(f"{file.name}: {file.url}")

# Pagination
files = api.list_files(limit=10, offset=10)
```

### Check Usage

```python
usage = api.get_usage_info()
print(f"Total storage used: {usage.total_bytes / 1024 / 1024:.2f} MB")
print(f"Files uploaded: {usage.files_uploaded}")
```

## Error Handling

The SDK uses standard Python exceptions:

```python
from requests.exceptions import HTTPError

try:
    api.upload_files(file)
except HTTPError as e:
    if e.response.status_code == 413:
        print("File too large")
    else:
        print(f"Upload failed: {e}")
except Exception as e:
    print(f"Unexpected error: {e}")
```

## API Reference

### UTApi Methods

All methods are defined in [`upyloadthing/client.py`](upyloadthing/client.py):

- `upload_files(files)` - Upload one or more files
- `delete_files(keys, key_type='file_key')` - Delete files by key or custom ID
- `list_files(limit=None, offset=None)` - List uploaded files
- `get_usage_info()` - Get account usage statistics

### Response Models

All response models are defined in [`upyloadthing/schemas.py`](upyloadthing/schemas.py):

- `UploadResult` - File upload result containing:
  - `ufs_url: str`
  - `url: str`
  - `app_url: str`
  - `file_hash: str`
  - `server_data: Dict | None`
- `DeleteFileResponse` - File deletion result containing:
  - `success: bool`
  - `deleted_count: int`
- `ListFileResponse` - File listing result containing:
  - `has_more: bool`
  - `files: List[FileData]`
- `UsageInfoResponse` - Usage statistics containing:
  - `total_bytes: int`
  - `app_total_bytes: int`
  - `files_uploaded: int`
  - `limit_bytes: int`

## License

MIT

