Skip to content

Commit

Permalink
Adds async client and refactors API implementation
Browse files Browse the repository at this point in the history
  • Loading branch information
farmisen committed Feb 13, 2025
1 parent 801e6fd commit c564094
Show file tree
Hide file tree
Showing 11 changed files with 989 additions and 188 deletions.
51 changes: 43 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -100,22 +100,57 @@ except Exception as e:

## API Reference

### UTApi Methods
### Client Classes

All methods are defined in [`upyloadthing/client.py`](upyloadthing/client.py):
Both clients provide the same methods with identical parameters, but different execution patterns:

- `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
#### UTApi (Synchronous)
```python
from upyloadthing import UTApi

api = UTApi(UTApiOptions(token="your-token"))
result = api.upload_files(file)
```

#### AsyncUTApi (Asynchronous)
```python
from upyloadthing import AsyncUTApi

api = AsyncUTApi(UTApiOptions(token="your-token"))
result = await api.upload_files(file)
```

### Methods

Both clients provide these methods:

- `upload_files(files: BinaryIO | List[BinaryIO], content_disposition: str = "inline", acl: str | None = "public-read") -> List[UploadResult]`
- Upload one or more files
- Returns list of upload results

- `delete_files(keys: str | List[str], key_type: str = "file_key") -> DeleteFileResponse`
- Delete one or more files by key or custom ID
- Returns deletion result

- `list_files(limit: int | None = None, offset: int | None = None) -> ListFileResponse`
- List uploaded files with optional pagination
- Returns file listing

- `get_usage_info() -> UsageInfoResponse`
- Get account usage statistics
- Returns usage information

### Response Models

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

- `UploadResult` - File upload result containing:
- `ufs_url: str`
- `file_key: str`
- `name: str`
- `size: int`
- `type: str`
- `url: str`
- `ufs_url: str`
- `app_url: str`
- `file_hash: str`
- `server_data: Dict | None`
Expand Down
66 changes: 66 additions & 0 deletions examples/async_main.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
import asyncio
from io import BytesIO
from typing import List

from upyloadthing.async_client import AsyncUTApi
from upyloadthing.schemas import UploadResult


async def main():
print("🚀 UploadThing API Demo (Async)\n")

# Initialize the client
api = AsyncUTApi()

# Get usage info
print("📊 Getting usage info...")
usage_info = await api.get_usage_info()
print(f"Total bytes used: {usage_info.total_bytes}")
print(f"Files uploaded: {usage_info.files_uploaded}")
print(f"Storage limit: {usage_info.limit_bytes}\n")

# List files
print("📋 Listing files...")
file_list = await api.list_files(limit=5)
print(
f"Fetched {len(file_list.files)} files, has more: {file_list.has_more}"
)
for file in file_list.files:
print(file)
print()

# Prepare test files
print("📤 Uploading test images...")

# Prepare PNG file
with open("./examples/test.png", "rb") as f:
image_content = f.read()
png_file = BytesIO(image_content)
png_file.name = "test.png"

# Prepare Jpeg file
with open("./examples/test.jpg", "rb") as f:
image_content = f.read()
jpeg_file = BytesIO(image_content)
jpeg_file.name = "test.jpg"

# Upload both files
upload_results: List[UploadResult] = await api.upload_files(
[png_file, jpeg_file], acl="public-read"
)

print("Upload results:")
for result in upload_results:
print(f"- {result.name}: {result.file_key}")
print()

# Delete the uploaded files
print("🗑️ Deleting test files...")
file_keys = [result.file_key for result in upload_results]
delete_result = await api.delete_files(file_keys)
print(f"Deleted {delete_result.deleted_count} file(s)")
print(f"Success: {delete_result.success}\n")


if __name__ == "__main__":
asyncio.run(main())
40 changes: 28 additions & 12 deletions examples/main.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
from io import BytesIO
from typing import List

from upyloadthing.client import UTApi
from upyloadthing.schemas import UploadResult
Expand Down Expand Up @@ -27,20 +28,35 @@ def main():
print(file)
print()

# Upload an image file
print("📤 Uploading test image...")
# Prepare test files
print("📤 Uploading test images...")

# Prepare PNG file
with open("./examples/test.png", "rb") as f:
image_content = f.read()
image_file = BytesIO(image_content)
image_file.name = "test.png"
upload_result: UploadResult = api.upload_files(
image_file, acl="public-read"
) # type: ignore
print(f"File uploaded with result: {upload_result}\n")

# Delete the uploaded file
print("🗑️ Deleting test file...")
delete_result = api.delete_files(upload_result.file_key)
png_file = BytesIO(image_content)
png_file.name = "test.png"

# Prepare Jpeg file
with open("./examples/test.jpg", "rb") as f:
image_content = f.read()
jpeg_file = BytesIO(image_content)
jpeg_file.name = "test.jpg"

# Upload both files
upload_results: List[UploadResult] = api.upload_files(
[png_file, jpeg_file], acl="public-read"
)

print("Upload results:")
for result in upload_results:
print(f"- {result.name}: {result.file_key}")
print()

# Delete the uploaded files
print("🗑️ Deleting test files...")
file_keys = [result.file_key for result in upload_results]
delete_result = api.delete_files(file_keys)
print(f"Deleted {delete_result.deleted_count} file(s)")
print(f"Success: {delete_result.success}\n")

Expand Down
Binary file added examples/test.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
21 changes: 20 additions & 1 deletion poetry.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ pyright = "^1.1.393"
ptpython = "^3.0.29"
pytest = "^8.3.4"
respx = "^0.22.0"
pytest-asyncio = "^0.23.2"

[tool.ruff]
line-length = 79
Expand Down
Loading

0 comments on commit c564094

Please sign in to comment.