Python SDK
Python SDK
Section titled “Python SDK”The official Python SDK for Splinterpic provides a Pythonic way to interact with the Splinterpic API.
Installation
Section titled “Installation”Using pip
Section titled “Using pip”pip install splinterpicUsing poetry
Section titled “Using poetry”poetry add splinterpicQuick Start
Section titled “Quick Start”from splinterpic import SplinterpicClient
client = SplinterpicClient(base_url='https://your-worker.workers.dev')
# Generate an imageimage = client.generate( prompt='A beautiful mountain landscape at sunset', model='@cf/black-forest-labs/flux-1-schnell')
print(f'Image URL: {image["r2_url"]}')Reference Implementation
Section titled “Reference Implementation”Until the official SDK is published, use this reference implementation:
import requestsfrom typing import Optional, Dict, List, Anyfrom dataclasses import dataclass
@dataclassclass SplinterpicConfig: base_url: str default_model: str = '@cf/black-forest-labs/flux-1-schnell' timeout: int = 30
class SplinterpicClient: """Official Splinterpic Python client"""
def __init__(self, base_url: str, default_model: Optional[str] = None, timeout: int = 30): self.base_url = base_url.rstrip('/') self.default_model = default_model or '@cf/black-forest-labs/flux-1-schnell' self.timeout = timeout self.session = requests.Session() self.session.headers.update({'Content-Type': 'application/json'})
def _request(self, method: str, endpoint: str, **kwargs) -> Any: """Make HTTP request to the API""" url = f'{self.base_url}{endpoint}'
try: response = self.session.request( method, url, timeout=self.timeout, **kwargs ) response.raise_for_status() return response.json() except requests.exceptions.HTTPError as e: error_data = e.response.json() if e.response.content else {} raise SplinterpicError( error_data.get('error', str(e)), status_code=e.response.status_code, details=error_data.get('details') ) except requests.exceptions.RequestException as e: raise SplinterpicError(f'Request failed: {str(e)}')
def generate( self, prompt: str, model: Optional[str] = None, template_id: Optional[str] = None ) -> Dict: """Generate a new AI image""" data = { 'prompt': prompt, 'model': model or self.default_model }
if template_id: data['template_id'] = template_id
return self._request('POST', '/api/generate', json=data)
def list_images(self, limit: int = 20, offset: int = 0) -> Dict: """List generated images""" params = {'limit': limit, 'offset': offset} return self._request('GET', '/api/images', params=params)
def get_image(self, image_id: str) -> Dict: """Get a specific image""" return self._request('GET', f'/api/images/{image_id}')
def delete_image(self, image_id: str) -> None: """Delete an image""" self._request('DELETE', f'/api/images/{image_id}')
def list_collections(self) -> Dict: """List all collections""" return self._request('GET', '/api/collections')
def create_collection(self, name: str, description: str) -> Dict: """Create a new collection""" data = {'name': name, 'description': description} return self._request('POST', '/api/collections', json=data)
def get_collection(self, collection_id: str) -> Dict: """Get collection details""" return self._request('GET', f'/api/collections/{collection_id}')
def get_collection_images(self, collection_id: str) -> Dict: """List images in a collection""" return self._request('GET', f'/api/collections/{collection_id}/images')
def delete_collection(self, collection_id: str) -> None: """Delete a collection""" self._request('DELETE', f'/api/collections/{collection_id}')
def list_models(self) -> Dict: """List available AI models""" return self._request('GET', '/api/models')
def get_model(self, model_id: str) -> Dict: """Get model details""" from urllib.parse import quote return self._request('GET', f'/api/models/{quote(model_id)}')
def get_usage_analytics(self) -> Dict: """Get usage analytics""" return self._request('GET', '/api/analytics/usage')
def get_cost_analytics(self) -> Dict: """Get cost analytics""" return self._request('GET', '/api/analytics/costs')
class SplinterpicError(Exception): """Base exception for Splinterpic SDK"""
def __init__(self, message: str, status_code: Optional[int] = None, details: Optional[Dict] = None): super().__init__(message) self.status_code = status_code self.details = details
# Export__all__ = ['SplinterpicClient', 'SplinterpicError', 'SplinterpicConfig']Usage Examples
Section titled “Usage Examples”Generate Images
Section titled “Generate Images”from splinterpic import SplinterpicClient
client = SplinterpicClient(base_url='https://your-worker.workers.dev')
# Single imageimage = client.generate( prompt='A futuristic city with flying cars, cyberpunk style', model='@cf/black-forest-labs/flux-1-schnell')
print(image)# {# 'id': 'img_abc123',# 'r2_url': 'https://...',# 'created_at': '2024-01-15T10:30:00.000Z'# }Batch Generation
Section titled “Batch Generation”from concurrent.futures import ThreadPoolExecutor
prompts = [ 'Mountain landscape at sunrise', 'Ocean waves during golden hour', 'Forest path in autumn']
def generate_image(prompt): return client.generate(prompt=prompt)
# Generate in parallelwith ThreadPoolExecutor(max_workers=3) as executor: images = list(executor.map(generate_image, prompts))
print(f'Generated {len(images)} images')List and Filter Images
Section titled “List and Filter Images”# Get first 50 imagesresponse = client.list_images(limit=50, offset=0)images = response['images']pagination = response['pagination']
print(f"Found {pagination['total']} images")
# Paginate through all imagesdef get_all_images(): all_images = [] offset = 0 limit = 100
while True: response = client.list_images(limit=limit, offset=offset) all_images.extend(response['images'])
if not response['pagination']['has_more']: break
offset += limit
return all_images
all_images = get_all_images()print(f'Total images: {len(all_images)}')Manage Collections
Section titled “Manage Collections”# Create a collectioncollection = client.create_collection( name='Marketing Campaign 2024', description='Q1 social media assets')
print(f"Created collection: {collection['id']}")
# List all collectionscollections = client.list_collections()for coll in collections['collections']: print(f"- {coll['name']}")
# Get collection detailsdetails = client.get_collection(collection['id'])print(details)
# Delete a collectionclient.delete_collection(collection['id'])Work with Models
Section titled “Work with Models”# List all available modelsmodels_response = client.list_models()
for model in models_response['models']: print(f"{model['name']}: ${model['cost_per_image']}/image")
# Get specific model detailsflux_model = client.get_model('@cf/black-forest-labs/flux-1-schnell')print(flux_model)Track Analytics
Section titled “Track Analytics”# Get usage statisticsusage = client.get_usage_analytics()print(f"Total images generated: {usage['total_images']}")
# Get cost analyticscosts = client.get_cost_analytics()print(f"Total cost: ${costs['total_cost']}")print(f"Average per image: ${costs['average_cost']}")Error Handling
Section titled “Error Handling”Basic Error Handling
Section titled “Basic Error Handling”from splinterpic import SplinterpicClient, SplinterpicError
client = SplinterpicClient(base_url='https://your-worker.workers.dev')
try: image = client.generate( prompt='A beautiful landscape', model='@cf/black-forest-labs/flux-1-schnell' )except SplinterpicError as e: print(f'Generation failed: {e}') print(f'Status code: {e.status_code}') print(f'Details: {e.details}')Advanced Error Handling with Retries
Section titled “Advanced Error Handling with Retries”import timefrom splinterpic import SplinterpicClient, SplinterpicError
def generate_with_retry(client, prompt, max_retries=3): """Generate image with automatic retries""" for attempt in range(max_retries): try: return client.generate(prompt=prompt) except SplinterpicError as e: if attempt == max_retries - 1: raise
wait_time = (attempt + 1) * 1.0 print(f'Retry {attempt + 1}/{max_retries} after {wait_time}s...') time.sleep(wait_time)
client = SplinterpicClient(base_url='https://your-worker.workers.dev')image = generate_with_retry(client, 'A beautiful landscape')Context Manager
Section titled “Context Manager”from contextlib import contextmanager
@contextmanagerdef splinterpic_client(base_url): """Context manager for Splinterpic client""" client = SplinterpicClient(base_url=base_url) try: yield client finally: client.session.close()
# Usagewith splinterpic_client('https://your-worker.workers.dev') as client: image = client.generate(prompt='A beautiful landscape') print(image['r2_url'])Type Hints
Section titled “Type Hints”Full type annotations for better IDE support:
from typing import TypedDict, Optional, List
class Image(TypedDict): id: str prompt: str model: str r2_key: str r2_url: str width: int height: int created_at: str user_id: str cost: float is_deleted: bool
class Pagination(TypedDict): limit: int offset: int total: int has_more: bool
class ListImagesResponse(TypedDict): images: List[Image] pagination: Pagination
class Collection(TypedDict): id: str name: str description: str created_at: str user_id: str
class Model(TypedDict): id: str name: str description: str cost_per_image: float is_recommended: boolAsync Support
Section titled “Async Support”For async/await support, use httpx:
import httpxfrom typing import Optional, Dict, Any
class AsyncSplinterpicClient: """Async Splinterpic Python client"""
def __init__(self, base_url: str, default_model: Optional[str] = None): self.base_url = base_url.rstrip('/') self.default_model = default_model or '@cf/black-forest-labs/flux-1-schnell' self.client = httpx.AsyncClient( headers={'Content-Type': 'application/json'}, timeout=30.0 )
async def _request(self, method: str, endpoint: str, **kwargs) -> Any: """Make async HTTP request to the API""" url = f'{self.base_url}{endpoint}'
try: response = await self.client.request(method, url, **kwargs) response.raise_for_status() return response.json() except httpx.HTTPStatusError as e: error_data = e.response.json() if e.response.content else {} raise SplinterpicError( error_data.get('error', str(e)), status_code=e.response.status_code )
async def generate( self, prompt: str, model: Optional[str] = None ) -> Dict: """Generate a new AI image""" data = { 'prompt': prompt, 'model': model or self.default_model } return await self._request('POST', '/api/generate', json=data)
async def close(self): """Close the HTTP client""" await self.client.aclose()
async def __aenter__(self): return self
async def __aexit__(self, exc_type, exc_val, exc_tb): await self.close()
# Usageimport asyncio
async def main(): async with AsyncSplinterpicClient('https://your-worker.workers.dev') as client: image = await client.generate(prompt='A beautiful landscape') print(image['r2_url'])
asyncio.run(main())Flask Integration
Section titled “Flask Integration”from flask import Flask, request, jsonifyfrom splinterpic import SplinterpicClient
app = Flask(__name__)client = SplinterpicClient(base_url='https://your-worker.workers.dev')
@app.route('/generate', methods=['POST'])def generate_image(): try: data = request.get_json() prompt = data.get('prompt')
if not prompt: return jsonify({'error': 'Prompt is required'}), 400
image = client.generate(prompt=prompt) return jsonify(image) except Exception as e: return jsonify({'error': str(e)}), 500
if __name__ == '__main__': app.run(debug=True)FastAPI Integration
Section titled “FastAPI Integration”from fastapi import FastAPI, HTTPExceptionfrom pydantic import BaseModelfrom splinterpic import SplinterpicClient, SplinterpicError
app = FastAPI()client = SplinterpicClient(base_url='https://your-worker.workers.dev')
class GenerateRequest(BaseModel): prompt: str model: str = '@cf/black-forest-labs/flux-1-schnell'
@app.post('/generate')async def generate_image(request: GenerateRequest): try: image = client.generate( prompt=request.prompt, model=request.model ) return image except SplinterpicError as e: raise HTTPException(status_code=500, detail=str(e))
@app.get('/images')async def list_images(limit: int = 20, offset: int = 0): try: return client.list_images(limit=limit, offset=offset) except SplinterpicError as e: raise HTTPException(status_code=500, detail=str(e))Django Integration
Section titled “Django Integration”from django.http import JsonResponsefrom django.views import Viewfrom splinterpic import SplinterpicClientimport json
client = SplinterpicClient(base_url='https://your-worker.workers.dev')
class GenerateImageView(View): def post(self, request): try: data = json.loads(request.body) prompt = data.get('prompt')
if not prompt: return JsonResponse({'error': 'Prompt is required'}, status=400)
image = client.generate(prompt=prompt) return JsonResponse(image) except Exception as e: return JsonResponse({'error': str(e)}, status=500)
# urls.pyfrom django.urls import pathfrom .views import GenerateImageView
urlpatterns = [ path('api/generate/', GenerateImageView.as_view()),]CLI Tool
Section titled “CLI Tool”Create a simple CLI tool:
import clickfrom splinterpic import SplinterpicClient
@click.group()@click.option('--base-url', envvar='SPLINTERPIC_API_URL', required=True)@click.pass_contextdef cli(ctx, base_url): """Splinterpic CLI tool""" ctx.obj = SplinterpicClient(base_url=base_url)
@cli.command()@click.argument('prompt')@click.option('--model', default='@cf/black-forest-labs/flux-1-schnell')@click.pass_objdef generate(client, prompt, model): """Generate an image""" image = client.generate(prompt=prompt, model=model) click.echo(f"Generated: {image['r2_url']}")
@cli.command()@click.option('--limit', default=20)@click.pass_objdef list(client, limit): """List images""" response = client.list_images(limit=limit) for img in response['images']: click.echo(f"{img['id']}: {img['prompt']}")
if __name__ == '__main__': cli()Usage:
export SPLINTERPIC_API_URL=https://your-worker.workers.devpython cli.py generate "A beautiful landscape"python cli.py list --limit=10Next Steps
Section titled “Next Steps”- JavaScript SDK - Use Splinterpic with JavaScript/Node.js JavaScript docs →
- API Reference - Explore the REST API directly API docs →
- Flask Tutorial - Build a Flask app with Splinterpic Tutorial →
- FastAPI Tutorial - Build a FastAPI app with Splinterpic Tutorial →