Skip to main content

A client library for generating images through the flix-imagen API

Project description

Imagen SDK

A proprietary client library for generating images through the flix-imagen API.

Authorized Flixstock users only. A signed runtime license file is required before the SDK can be used.

Python compatibility

  • Supported: Python 3.9 through 3.14 (CPython and PyPy)
  • Wheel: one universal py3-none-any wheel works across all supported versions
  • Floor: Python 3.9 (required by the cryptography dependency)

Test locally across versions (requires tox and multiple Python installs):

pip install -e ".[dev]"
tox

CI runs the test suite on Python 3.9–3.13 via bitbucket-pipelines.yml.

Installation

pip install imagen-sdk

Runtime license file

Before creating a client, obtain an RSA-signed license file from Flixstock. The SDK verifies signatures using a public key bundled in the package; the private key never ships with the SDK.

The SDK checks for a license in this order:

  1. license_path argument to ImagenClient
  2. IMAGEN_SDK_LICENSE environment variable
  3. ./imagen-sdk.license or ./license.json in the working directory
  4. ~/.config/imagen-sdk/license.json

Example license format: see license.example.json.

Allowed email domains: @flixstock.com, @imageedit.ai.

Key setup (Flixstock admins, one-time)

Generate an RSA key pair. The public key is committed to the repo; the private key stays local.

pip install cryptography
python scripts/generate_keys.py
  • Public key: src/imagen_sdk/keys/license_public.pem (bundled in the wheel)
  • Private key: keys/license_private.pem (gitignored — store securely)

Issue a license (Flixstock admins)

python scripts/issue_license.py \
  --licensee "Jane Doe" \
  --email "jane.doe@flixstock.com" \
  --output imagen-sdk.license

Optional: --private-key /path/to/license_private.pem or set IMAGEN_SDK_PRIVATE_KEY.

Usage

The SDK is a production workflow layer over the flix-imagen HTTP API. It handles validation, model-agnostic parameter normalization, job creation, polling, output downloads, batch orchestration with manifests/resume, typed errors, and idempotency. See requirements.md for the full design and what the backend currently supports.

Client setup

from imagen_sdk import ImagenClient

client = ImagenClient(
    api_key="pk-your-project-key",                 # or "uk-..." user key
    base_url="https://api-fliximagen.flixstock.com",
    # license_path="/path/to/imagen-sdk.license",  # or via IMAGEN_SDK_LICENSE
    max_concurrency=10,
    timeout=60,
    poll_interval=2,
    max_poll_interval=15,
    log_level="INFO",
)

A signed runtime license is still required (see below). Authentication to the API uses the X-API-Key header. With a uk- user key, pass project_name=... to generate(...) or set it on the client.

Single generation

result = client.generate(
    model="nano_banana_2",                         # stable SDK alias from provider_registry.json
    prompt="Female model wearing a black blazer and white trousers",
    input_image="https://cdn.example.com/inputs/blazer.jpg",  # hosted HTTPS URL
    output_path="./outputs/blazer.png",
    parameters={
        "aspect_ratio": "3:4",
        "image_count": 1,
        "resolution": "2K",
        "output_format": "png",
    },
)

print(result.job_id, result.status)
print(result.outputs[0].saved_to)

Models are referenced by stable aliases (ImagenClient.available_models()): nano_banana_2, nano_banana_pro, nano_banana_2_edit, nano_banana_pro_edit, gpt_image_2_edit, gpt_4o. You can also pass a raw model: generate(model="fal:fal-ai/flux/dev", ...) or generate(model="gemini-3.1-flash-image-preview", provider="vertex", ...).

Batch generation with manifest + resume

batch = client.generate_many(
    requests=[
        {
            "request_id": "sku_001",
            "model": "nano_banana_2",
            "prompt": "Model wearing SKU 001",
            "input_image": "https://cdn.example.com/inputs/sku_001.jpg",
            "output_path": "./outputs/sku_001.png",
            "parameters": {"aspect_ratio": "3:4", "output_format": "png"},
        },
    ],
    concurrency=10,
    save_manifest="./outputs/manifest.json",
    continue_on_error=True,
)

print(batch.total, batch.succeeded, batch.failed)

# Resume an interrupted batch (skips already-succeeded items):
client.resume_batch("./outputs/manifest.json", requests)

Async client

import asyncio
from imagen_sdk import AsyncImagenClient

async def main():
    async with AsyncImagenClient(api_key="pk-...") as client:
        results = await client.generate_many(
            [
                {"model": "nano_banana_2", "prompt": "red dress",
                 "input_image": "https://cdn/1.jpg", "output_path": "./out/1.png"},
                {"model": "nano_banana_2", "prompt": "blue dress",
                 "input_image": "https://cdn/2.jpg", "output_path": "./out/2.png"},
            ],
            concurrency=10,
        )
        print(results.succeeded)

asyncio.run(main())

Dry run

preview = client.generate(
    model="nano_banana_2",
    prompt="denim jacket",
    input_image="https://cdn/in.jpg",
    parameters={"aspect_ratio": "3:4", "image_count": 4},
    dry_run=True,
)
print(preview.normalized_payload)   # provider input_fields, no job created
print(preview.uploads_required)

Low-level API

dto = client.create_job(model="nano_banana_2", prompt="...",
                        input_image="https://cdn/in.jpg")
status = client.wait_for_job(dto["id"])
client.download_outputs(status["output_urls"], job_id=dto["id"],
                        output_dir="./outputs/")

Errors

from imagen_sdk import JobFailedError, ValidationError, RateLimitError

try:
    client.generate(model="nano_banana_2", prompt="...")
except ValidationError as exc:      # caught locally before any API call
    print(exc.details)
except JobFailedError as exc:
    print(exc.job_id, exc.error_code, exc.retryable)

All errors derive from SDKError and carry code, status_code, job_id, request_id, and retryable.

Output overwrite policy

generate(..., on_existing=...) accepts error (default), overwrite, rename (writes out_1.webp, out_2.webp, ...), or skip.

Local file uploads

Local files (input_image="./in.jpg", Path(...), etc.) are uploaded automatically to S3/CDN via the Flixstudio Pegasus presign service — the same flow the web UI uses:

  1. POST https://api-pegasus.flixstudio.io/api/v1/util/s3PutPreSignedUrl with {"key", "bucketName", "mimeType"}{"url": "<signed PUT URL>"}
  2. PUT the bytes to the signed URL
  3. The public URL https://fxgati.flixstock.com/<key> is passed into the job
result = client.generate(
    model="nano_banana_2",
    prompt="red dress",
    input_image="./inputs/front.jpg",   # local file -> uploaded automatically
    output_path="./outputs/front.png",
)
# Or upload manually:
up = client.upload_file("./inputs/front.jpg")
print(up.cdn_url)

Configurable on the client: enable_uploads (default True), pegasus_presign_url, upload_bucket (fxgati), cdn_host (fxgati.flixstock.com), upload_key_prefix (Flix_ImageGen), and pegasus_token (sent as Authorization: Bearer if the service requires it). Set enable_uploads=False to force hosted-URL-only inputs.

Backend limitations (current flix-imagen state)

  • Cancellation, webhooks, and server-side idempotency are not yet available. cancel_job() raises NotSupportedError; the SDK still sends an Idempotency-Key header so it works the moment the backend adds support.

Legacy construction

from imagen_sdk import ImagenClient, LicenseError

try:
    client = ImagenClient(api_key="pk-...", license_path="/path/to/imagen-sdk.license")
except LicenseError as exc:
    print(exc)

Or set the environment variable:

export IMAGEN_SDK_LICENSE=/path/to/imagen-sdk.license

Development

python -m venv .venv
.venv\Scripts\activate          # Windows
# source .venv/bin/activate     # macOS/Linux

pip install -e ".[dev]"
python scripts/generate_keys.py   # if keys do not exist yet
python scripts/issue_license.py --licensee "Dev User" --email "dev@flixstock.com"
pytest

Publishing to PyPI

CI/CD (Bitbucket Pipelines)

Releases are published automatically when you push a version tag.

  1. Bump version in pyproject.toml and __version__ in src/imagen_sdk/__init__.py.
  2. Commit and push.
  3. Create and push a matching tag:
git tag v0.0.2
git push origin v0.0.2

The v* tag pipeline runs tests, verifies the tag matches the package version, builds, and uploads to PyPI.

Manual TestPyPI publish: Pipelines → Run pipeline → publish-testpypi.

Bitbucket repository variables

Add these under Repository settings → Pipelines → Repository variables:

Variable Secured Value
TWINE_USERNAME No __token__
TWINE_PASSWORD Yes Production PyPI API token (full value, including pypi- prefix)
TESTPYPI_TWINE_PASSWORD Yes TestPyPI API token (only needed for the publish-testpypi custom pipeline)

Create tokens at:

Scope tokens to the imagen-sdk project when possible.

Manual publish

Follow the Python Packaging User Guide.

1. Install build tools

pip install --upgrade pip build twine

2. Bump the version

Update version in pyproject.toml and __version__ in src/imagen_sdk/__init__.py. PyPI does not allow re-uploading the same version.

3. Build distribution archives

# Windows PowerShell
Remove-Item -Recurse -Force dist, build -ErrorAction SilentlyContinue
python -m build

This produces in dist/:

  • imagen_sdk-<version>.tar.gz — source distribution
  • imagen_sdk-<version>-py3-none-any.whl — wheel

4. Test on TestPyPI (recommended)

  1. Register at test.pypi.org and verify your email.
  2. Create an API token at test.pypi.org/manage/account/#api-tokens.
  3. Upload:
python -m twine upload --repository testpypi dist/*

When prompted:

  • Username: __token__
  • Password: your API token (including the pypi- prefix)
  1. Verify install:
pip install --index-url https://test.pypi.org/simple/ --no-deps imagen-sdk
  1. Check: https://test.pypi.org/project/imagen-sdk/

5. Publish to PyPI

  1. Register at pypi.org (separate from TestPyPI).
  2. Confirm imagen-sdk is available on pypi.org.
  3. Create a production API token at pypi.org/manage/account/#api-tokens.
  4. Upload:
python -m twine upload dist/*
  1. Install from PyPI:
pip install imagen-sdk

Optional: store credentials in .pypirc

[distutils]
index-servers =
    pypi
    testpypi

[pypi]
username = __token__
password = pypi-...

[testpypi]
repository = https://test.pypi.org/legacy/
username = __token__
password = pypi-...

Never commit .pypirc or API tokens to version control.

License

Proprietary — see LICENSE. Unauthorized use, copying, or distribution is prohibited.

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

imagen_sdk-0.1.0.tar.gz (49.2 kB view details)

Uploaded Source

Built Distribution

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

imagen_sdk-0.1.0-py3-none-any.whl (50.3 kB view details)

Uploaded Python 3

File details

Details for the file imagen_sdk-0.1.0.tar.gz.

File metadata

  • Download URL: imagen_sdk-0.1.0.tar.gz
  • Upload date:
  • Size: 49.2 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.13

File hashes

Hashes for imagen_sdk-0.1.0.tar.gz
Algorithm Hash digest
SHA256 65cc0914356fc1511cfa8725018844812bd77054cd57230bc26a79cf99c27756
MD5 9b8aeade379417b24adbe2dda9d7c677
BLAKE2b-256 ad075877b2d7d99248582c7a13d199ebefc6ea0c8afddf38b59474585f77c9f8

See more details on using hashes here.

File details

Details for the file imagen_sdk-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: imagen_sdk-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 50.3 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.13

File hashes

Hashes for imagen_sdk-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 a92999f65a655ce48583ee4b2047a4fb201c73144eab8a4805106b8a5bb445f3
MD5 2fc27a045dbb0043373fc7c72b22bd7a
BLAKE2b-256 0ae3409c704585c760549b7702039751aae4227fc390495c0ecd2722b590482a

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