Skip to main content

Official Python SDK for the Bluma API

Project description

bluma

Official Python SDK for the Bluma API

Installation

pip install bluma

Quick Start

from bluma import Bluma

bluma = Bluma(api_key="your_api_key")

# Generate a video
video = bluma.videos.create(
    template_id="meme-dialogue",
    context={"prompt": "Create a funny dialogue between a programmer and their computer"}
)

print(f"Video ID: {video.id}")

# Wait for completion
completed = bluma.videos.wait_for(video.id)
print(f"Video ready: {completed.url}")

Features

  • Type hints for full IDE support
  • Automatic retries with exponential backoff
  • Webhook verification utilities
  • Polling helpers for video completion
  • Custom exception classes for each error type
  • Context manager support
  • Pydantic models for response validation

Configuration

from bluma import Bluma

bluma = Bluma(
    api_key="your_api_key",
    base_url="https://api.bluma.app/api/v1",  # optional
    timeout=30.0,  # seconds
    max_retries=3,
    retry_delay=1.0,  # seconds
    retry_multiplier=2.0  # exponential backoff
)

API Reference

Videos

# Create video
video = bluma.videos.create(
    template_id="meme-dialogue",
    context={"prompt": "Create a funny video"},
    webhook_url="https://myapp.com/webhook",  # optional
    metadata={"user_id": "user_123"}  # optional
)

# Get video status
video = bluma.videos.get("batch_abc123")

# Wait for completion with progress
def on_progress(progress):
    print(f"Progress: {progress}%")

completed = bluma.videos.wait_for(
    "batch_abc123",
    poll_interval=5.0,
    timeout=600.0,
    on_progress=on_progress
)

# Download video
download = bluma.videos.download("batch_abc123")
print(download.download_url)

Templates

# List all templates
templates = bluma.templates.list()

# Get template details
template = bluma.templates.get("meme-dialogue")

Credits

# Get balance
balance = bluma.credits.get_balance()
print(f"{balance.credits} credits remaining")

# Get history
history = bluma.credits.get_history(limit=50)
for txn in history.transactions:
    print(f"{txn.description}: {txn.amount}")

Template Variants (Configuration Presets)

Save and reuse template configurations:

# Create a variant preset
variant = bluma.variants.create(
    template_id="meme-dialogue",
    name="Funny Tone Preset",
    settings={
        "systemPrompt": "Use a funny, lighthearted tone",
        "captionPrompt": "Create engaging captions with emojis",
        "compositionProps": {
            "voiceId": "female-casual",
            "primaryColor": "#FF69B4"
        }
    }
)

# List variant presets for a template
variants = bluma.variants.list("meme-dialogue")

# Get variant details
variant = bluma.variants.get("meme-dialogue", "variant_xyz789")

# Update variant preset
updated = bluma.variants.update(
    template_id="meme-dialogue",
    variant_id="variant_xyz789",
    settings={"systemPrompt": "Updated tone instructions"}
)

# Delete variant
bluma.variants.delete("meme-dialogue", "variant_xyz789")

Asset Collections

Organize your brand assets into collections:

# Create a collection
collection = bluma.collections.create(
    name="Product Photos",
    description="High-quality product photography"
)

# List all collections
collections = bluma.collections.list()

# Get collection details
collection = bluma.collections.get("collection_abc123")

# Rename collection
bluma.collections.rename("collection_abc123", "New Name")

# Add assets to collection
bluma.collections.add_assets(
    collection_id="collection_abc123",
    asset_ids=["asset_1", "asset_2"]
)

# Remove asset from collection
bluma.collections.remove_asset("collection_abc123", "asset_1")

# List assets in collection
assets = bluma.collections.list_assets("collection_abc123")

# Delete collection
bluma.collections.delete("collection_abc123")

Assets

Upload and manage brand assets:

import requests

# Upload an asset (returns presigned URL)
upload_response = bluma.assets.upload(
    file_name="product.jpg",
    file_type="image/jpeg",
    collection_ids=["collection_abc123"]  # optional
)

# Upload file to presigned URL
with open("product.jpg", "rb") as f:
    requests.put(upload_response.upload_url, data=f)

print(f"CDN URL: {upload_response.cdn_url}")

# Get asset details
asset = bluma.assets.get("asset_abc123")

# List assets with filters
assets = bluma.assets.list(
    file_type="image",  # optional filter
    collection_id="collection_abc123",  # optional filter
    include_deleted=False
)

# Get random asset from collection
random_asset = bluma.assets.get_random(
    file_type="image",
    collection_id="collection_abc123",
    used_asset_ids=["asset_1", "asset_2"]  # Exclude these
)

# Rename asset
bluma.assets.rename("asset_abc123", "New Asset Name")

# Soft delete asset
bluma.assets.delete("asset_abc123")

# Recover deleted asset
bluma.assets.recover("asset_abc123")

Webhooks

# Create webhook
webhook = bluma.webhooks.create(
    url="https://myapp.com/webhooks/bluma",
    events=["video.completed", "video.failed"]
)
print(f"Secret: {webhook.secret}")  # Save this!

# List webhooks
webhooks = bluma.webhooks.list()

# Delete webhook
bluma.webhooks.delete("webhook_abc123")

# Get deliveries
deliveries = bluma.webhooks.get_deliveries("webhook_abc123")

Webhook Verification

from bluma import verify_webhook
from flask import Flask, request

app = Flask(__name__)

@app.route('/webhooks/bluma', methods=['POST'])
def webhook():
    signature = request.headers.get('X-Bluma-Signature')
    payload = request.get_data()

    try:
        event = verify_webhook(payload, signature, 'your_webhook_secret')
        print(f"Event: {event['type']}")
        return '', 200
    except ValueError:
        return 'Unauthorized', 401

Error Handling

from bluma import (
    ValidationError,
    AuthenticationError,
    InsufficientCreditsError,
    RateLimitError,
    NotFoundError,
    APIError
)

try:
    video = bluma.videos.create(...)
except ValidationError as error:
    print(f"Invalid input: {error.detail}")
except InsufficientCreditsError:
    print("Out of credits!")
except RateLimitError as error:
    print(f"Rate limited. Retry after {error.retry_after}s")
except APIError as error:
    print(f"API error: {error.status} - {error.detail}")

Context Manager

with Bluma(api_key="your_api_key") as client:
    video = client.videos.create(
        template_id="meme-dialogue",
        context={"prompt": "Test"}
    )
    print(video.id)

# Client is automatically closed here

Type Hints

Full type hint support for IDE autocompletion:

from bluma import Bluma, Video, VideoStatus

bluma = Bluma(api_key="your_api_key")

video: Video = bluma.videos.get("batch_abc123")

if video.status == VideoStatus.COMPLETED:
    print(video.url)

Development

Setup

# Install with dev dependencies
pip install -e ".[dev]"

# Run tests
pytest

# Run type checking
mypy bluma

# Format code
black bluma tests

Testing

# Run all tests
pytest

# Run with coverage
pytest --cov=bluma --cov-report=html

License

MIT

Support

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

bluma-1.2.0.tar.gz (39.8 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

bluma-1.2.0-py3-none-any.whl (13.6 kB view details)

Uploaded Python 3

File details

Details for the file bluma-1.2.0.tar.gz.

File metadata

  • Download URL: bluma-1.2.0.tar.gz
  • Upload date:
  • Size: 39.8 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.14.0

File hashes

Hashes for bluma-1.2.0.tar.gz
Algorithm Hash digest
SHA256 f20864b2380732a59426ab0ac66de08aa5e9471a83d16301a57cf28bee8f0a0f
MD5 85999f5849d78dcde79bf9948cbd29fb
BLAKE2b-256 14fefd62085ee0f2833114d6ccc3e0dcf66499d3677143263e7ee233e5d3ff1b

See more details on using hashes here.

File details

Details for the file bluma-1.2.0-py3-none-any.whl.

File metadata

  • Download URL: bluma-1.2.0-py3-none-any.whl
  • Upload date:
  • Size: 13.6 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.14.0

File hashes

Hashes for bluma-1.2.0-py3-none-any.whl
Algorithm Hash digest
SHA256 385a0679bb186a903277945ce45bb35ff0ba28bf908b70b1a56c78173842e013
MD5 5a717fecd937830a5d3c90ca5574a2a7
BLAKE2b-256 1da60f3e6e51ce28371583063c91d2627204c7f141cd12196782b816a617d3c9

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page