Skip to content

siray-ai/siray-python

Repository files navigation

Siray Python SDK

PyPI version Python version License

The official Python client library for Siray AI - a platform for AI-powered image and video generation.

Installation

Install the package using pip:

pip install siray

Or install from source:

git clone https://github.com/siray-ai/siray-python.git
cd siray-python
pip install .

Quick Start

Authentication

Get your API key from Siray AI Dashboard and set it as an environment variable:

export SIRAY_API_KEY="your-api-key-here"

Or pass it directly when initializing the client:

from siray import Siray

client = Siray(api_key="your-api-key-here")

Image Generation

Image-to-Image (Flux 1.1 Pro Ultra I2i)

from siray import Siray

client = Siray()

# Optional: load a local file and get a ready-to-use data URI
local_image = client.load_from_local("~/Pictures/input.jpg")

# Generate image asynchronously
response = client.image.generate_async(
    model="black-forest-labs/flux-1.1-pro-ultra-i2i",
    prompt="A beautiful sunset over mountains with vibrant colors",
    image=local_image,
)

print(f"Task ID: {response.task_id}")

client.load_from_local(path) reads the file, infers the MIME type, and returns a data:<mime>;base64,... string accepted by the API. This is handy when you do not have a public URL for the asset you want to condition on.

Query Task Status

# After starting an async generation, query its status
status = client.image.query_task(response.task_id)

if status.is_completed():
    print(f"âś“ Completed!")
    for i, url in enumerate(status.outputs, 1):
        print(f"  Image {i}: {url}")
elif status.is_processing():
    print(f"⏳ Processing... {status.progress}")
elif status.is_failed():
    print(f"âś— Failed: {status.fail_reason}")

Run and Wait for Completion

# Convenience helper that starts a task and polls until it finishes
status = client.image.run(
    model="black-forest-labs/flux-1.1-pro-ultra-i2i",
    prompt="A futuristic city skyline at dusk",
    image="https://example.com/input-image.jpg",
    poll_interval=2.0,  # optional, defaults to 2 seconds
)

print(f"Final status: {status.status}")
if status.is_completed():
    print(status.outputs)

See examples/blocking_generation.py for a full runnable script that uses image.run().

Video Generation

from siray import Siray

client = Siray()

# Generate video asynchronously
response = client.video.generate_async(
    model="your-video-model",
    prompt="A cat playing piano in a cozy room"
)

print(f"Task ID: {response.task_id}")

# Or block until the task finishes
status = client.video.run(
    model="your-video-model",
    prompt="A cat playing piano in a cozy room",
)
print(status.status)

A complete blocking flow for both media types lives in examples/blocking_generation.py.

API Reference

Client

Siray(api_key=None, base_url="https://api.siray.ai")

Main client for interacting with Siray AI API.

Parameters:

  • api_key (str, optional): API key for authentication. If not provided, reads from SIRAY_API_KEY environment variable.
  • base_url (str, optional): Base URL for the API. Default: https://api.siray.ai

Attributes:

  • image: Image generation namespace
  • video: Video generation namespace

Image

image.generate_async(model, prompt, image, **kwargs)

Generate an image asynchronously using image-to-image models.

Parameters:

  • model (str): Model identifier (e.g., "black-forest-labs/flux-1.1-pro-ultra-i2i")
  • prompt (str): Text prompt for image generation
  • image (str): Input image (URL or base64 encoded string)
  • **kwargs: Additional model-specific parameters

Returns: GenerationResponse object with the following attributes:

  • task_id (str): Unique identifier for the generation task
  • raw_response (dict): Raw API response data

image.query_task(task_id)

Query the status and result of an image generation task.

Parameters:

  • task_id (str): Task ID returned from the image generation request

Returns: TaskStatus object with the following attributes:

  • code (str): Response code (e.g., 'success')
  • message (str): Response message
  • task_id (str): Task identifier
  • action (str): Action type (e.g., 'imageGenerate')
  • status (str): Current task status (e.g., 'SUCCESS', 'PENDING', 'FAILED')
  • outputs (List[str]): List of output URLs
  • fail_reason (str | None): Failure reason if task failed
  • progress (str | None): Progress string (e.g., '100%')
  • submit_time (int | None): Unix timestamp when submitted
  • start_time (int | None): Unix timestamp when started
  • finish_time (int | None): Unix timestamp when finished
  • result (property): First output URL (for backward compatibility)
  • progress_percent (property): Progress as integer (0-100)
  • is_completed() (method): Check if task is completed
  • is_processing() (method): Check if task is still processing
  • is_failed() (method): Check if task has failed

Example:

# Start async generation
response = client.image.generate_async(
    model="black-forest-labs/flux-kontext-i2i-max",
    prompt="A beautiful sunset",
    image="https://example.com/input.jpg"
)

# Query task status
status = client.image.query_task(response.task_id)

if status.is_completed():
    print(f"Generated {len(status.outputs)} image(s)")
    for url in status.outputs:
        print(f"  - {url}")
elif status.is_failed():
    print(f"Error: {status.fail_reason}")

image.run(model, prompt, poll_interval=2.0, timeout=None, **kwargs)

Start an async image generation and continuously poll its status until it completes or fails.

Parameters:

  • model (str): Model identifier
  • prompt (str): Text prompt
  • poll_interval (float, optional): Seconds between status checks (minimum 0.1). Default: 2.0
  • timeout (float | None, optional): Maximum seconds to wait before raising TimeoutError. None disables the timeout.
  • **kwargs: Additional model-specific parameters

Returns: TaskStatus with the final state of the task.

Raises:

  • TimeoutError: If the task is still processing when the timeout is reached

Video

video.generate_async(model, prompt, **kwargs)

Generate a video asynchronously.

Parameters:

  • model (str): Model identifier
  • prompt (str): Text prompt for video generation
  • **kwargs: Additional model-specific parameters (e.g., duration, fps)

Returns: GenerationResponse object with the following attributes:

  • task_id (str): Unique identifier for the generation task
  • raw_response (dict): Raw API response data

video.query_task(task_id)

Query the status and result of a video generation task.

Parameters:

  • task_id (str): Task ID returned from the video generation request

Returns: TaskStatus object (same structure as image query)

Example:

# Start async generation
response = client.video.generate_async(
    model="your-video-model",
    prompt="A cat playing piano"
)

# Query task status
status = client.video.query_task(response.task_id)

if status.is_completed():
    print(f"Generated {len(status.outputs)} video(s)")
    for url in status.outputs:
    print(f"  - {url}")
elif status.is_failed():
    print(f"Error: {status.fail_reason}")

video.run(model, prompt, poll_interval=2.0, timeout=None, **kwargs)

Start an async video generation and wait for it to complete by polling the task status.

Parameters: Same as image.run.

Returns: Final TaskStatus.

Raises:

  • TimeoutError: If the task does not finish before the timeout

Response Models

The SDK provides typed response objects instead of raw dictionaries:

GenerationResponse

Returned by generate_async() methods. Contains:

  • task_id: Unique task identifier
  • raw_response: Raw API response data
  • to_dict(): Convert to dictionary

TaskStatus

Returned by query_task() method. Contains:

  • code: Response code (e.g., 'success')
  • message: Response message
  • task_id: Task identifier
  • action: Action type (e.g., 'imageGenerate')
  • status: Current status (e.g., 'SUCCESS', 'PENDING', 'FAILED')
  • outputs: List of output URLs
  • fail_reason: Failure reason if task failed
  • progress: Progress string (e.g., '100%')
  • submit_time: Unix timestamp when submitted
  • start_time: Unix timestamp when started
  • finish_time: Unix timestamp when finished
  • result (property): First output URL (backward compatibility)
  • progress_percent (property): Progress as integer (0-100)
  • is_completed(): Check if completed
  • is_processing(): Check if processing
  • is_failed(): Check if failed
  • to_dict(): Convert to dictionary

Error Handling

The SDK provides specific exception classes for different error scenarios:

from siray import Siray, SirayError, AuthenticationError, BadRequestError

client = Siray()

try:
    result = client.image.generate_async(
        model="black-forest-labs/flux-1.1-pro-ultra-i2i",
        prompt="A beautiful sunset",
        image="https://example.com/image.jpg"
    )
except AuthenticationError as e:
    print(f"Authentication failed: {e.message}")
except BadRequestError as e:
    print(f"Invalid request: {e.message}")
    print(f"Error code: {e.code}")
    print(f"Error type: {e.error_type}")
except SirayError as e:
    print(f"API error: {e.message}")
    print(f"Status code: {e.status_code}")

Exception Types

  • SirayError: Base exception for all SDK errors
  • AuthenticationError: Raised when authentication fails (401)
  • BadRequestError: Raised when the request is invalid (400)
  • InternalServerError: Raised when the server encounters an error (500)
  • APIError: Raised for general API errors

Examples

See the examples directory for more comprehensive usage examples:

Development

Setup Development Environment

# Clone the repository
git clone https://github.com/siray-ai/siray-python.git
cd siray-python

# Install development dependencies
pip install -r requirements-dev.txt

# Install package in editable mode
pip install .

Running Tests

pytest tests/

Code Formatting

# Format code
black siray/

# Check code style
flake8 siray/

# Sort imports
isort siray/

# Type checking
mypy siray/

Contributing

Contributions are welcome! Please feel free to submit a Pull Request.

  1. Fork the repository
  2. Create your feature branch (git checkout -b feature/amazing-feature)
  3. Commit your changes (git commit -m 'Add some amazing feature')
  4. Push to the branch (git push origin feature/amazing-feature)
  5. Open a Pull Request

License

This project is licensed under the Apache License 2.0 - see the LICENSE file for details.

Support

Changelog

See CHANGELOG.md for a list of changes in each release.

About

No description, website, or topics provided.

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Languages