Documentation Index
Fetch the complete documentation index at: https://docs.gumnut.ai/llms.txt
Use this file to discover all available pages before exploring further.
Python SDK
The official Gumnut Python SDK provides a Pythonic interface to the Gumnut API with full type hints support for better IDE experience.
Installation
pip install gumnut-sdk
# or
poetry add gumnut-sdk
Quick Start
from gumnut import Gumnut
import os
client = Gumnut(
api_key=os.environ.get("GUMNUT_API_KEY")
)
# Upload an asset
with open('photo.jpg', 'rb') as f:
asset = client.assets.create(
asset_data=f,
device_asset_id='photo_001',
device_id='my_device',
file_created_at='2024-01-01T00:00:00Z',
file_modified_at='2024-01-01T00:00:00Z'
)
# Create an album
album = client.albums.create(
album_name='Vacation 2024',
description='Summer vacation photos'
)
# Add asset to album
client.albums.add_assets(
album_id=album.id,
asset_ids=[asset.id]
)
# Search for assets
results = client.search.query(
q="sunset beach",
limit=10
)
Key Features
- Python 3.8+ Support: Compatible with modern Python versions
- Type Hints: Full type annotations for better IDE support
- Async/Await Support: Built-in async client using httpx
- Automatic Retries: Configurable retry logic with exponential backoff
- Context Managers: Proper resource handling for file operations
- Comprehensive Error Handling: Detailed exception types
Async Support
Use the async client for better performance:
import asyncio
from gumnut import AsyncGumnut
async def main():
client = AsyncGumnut(
api_key=os.environ.get("GUMNUT_API_KEY")
)
# Async operations
assets = await client.assets.list()
albums = await client.albums.list()
# Process results concurrently
tasks = [
client.assets.get(asset.id)
for asset in assets[:5]
]
detailed_assets = await asyncio.gather(*tasks)
await client.aclose() # Clean up
asyncio.run(main())
File Uploads
Multiple ways to handle file uploads:
# File object
with open('photo.jpg', 'rb') as f:
asset = client.assets.create(
asset_data=f,
device_asset_id='unique_id',
device_id='my_device'
)
# Bytes
with open('photo.jpg', 'rb') as f:
data = f.read()
asset = client.assets.create(
asset_data=data,
device_asset_id='unique_id',
device_id='my_device'
)
# Path string (automatically opens file)
asset = client.assets.create(
asset_data='photo.jpg',
device_asset_id='unique_id',
device_id='my_device'
)
Configuration
from gumnut import Gumnut
client = Gumnut(
api_key="your_api_key",
max_retries=3,
timeout=60.0,
base_url="https://api.gumnut.ai" # Usually not needed
)
Error Handling
from gumnut import APIError, RateLimitError
try:
asset = client.assets.get('invalid_id')
except RateLimitError as e:
print(f"Rate limited. Retry after: {e.retry_after}s")
except APIError as e:
print(f"API Error: {e.status_code} - {e.message}")
print(f"Request ID: {e.request_id}")
Handle large result sets easily:
# Automatic pagination
all_assets = []
for page in client.assets.list_pages():
all_assets.extend(page.assets)
if len(all_assets) >= 1000: # Limit if needed
break
# Manual pagination
page1 = client.assets.list(limit=50)
page2 = client.assets.list(limit=50, offset=50)
# Async pagination
async for page in client.assets.list_pages_async():
for asset in page.assets:
await process_asset(asset)
Repository & Documentation
GitHub Repository: github.com/gumnut-ai/photos-sdk-python
For complete API documentation, examples, and advanced usage:
Common Use Cases
Batch Upload
import os
from pathlib import Path
def upload_directory(directory_path):
photos = Path(directory_path).glob('*.{jpg,jpeg,png,heic}')
for photo in photos:
with open(photo, 'rb') as f:
asset = client.assets.create(
asset_data=f,
device_asset_id=str(photo.stem),
device_id='batch_uploader',
file_created_at=photo.stat().st_ctime,
file_modified_at=photo.stat().st_mtime
)
print(f"Uploaded: {photo.name} -> {asset.id}")
Data Analysis
import pandas as pd
# Get all assets with metadata
assets = client.assets.list(limit=1000)
# Convert to DataFrame for analysis
df = pd.DataFrame([{
'id': asset.id,
'created_at': asset.created_at,
'camera_make': asset.exif_info.get('make'),
'camera_model': asset.exif_info.get('model'),
'has_faces': len(asset.faces) > 0
} for asset in assets])
# Analyze by camera
camera_stats = df.groupby(['camera_make', 'camera_model']).size()
print(camera_stats)
Next Steps