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

Full user guide: see USAGE.md for the complete instruction set — all generation modes, accepted parameters, and per-model allowed values (aspect ratios, resolutions, output formats, image counts).

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.2.tar.gz (49.3 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.2-py3-none-any.whl (50.4 kB view details)

Uploaded Python 3

File details

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

File metadata

  • Download URL: imagen_sdk-0.1.2.tar.gz
  • Upload date:
  • Size: 49.3 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.2.tar.gz
Algorithm Hash digest
SHA256 f21c43e2abd1b898c66898afa0e70364d13f8fb28ad372c1e59d1d36e595b30b
MD5 e838ff51f6b3d10e1a29ce4922f503d2
BLAKE2b-256 55ed176469027259586830f16a2337c850c3954e31a8929a441be06a28e5c519

See more details on using hashes here.

File details

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

File metadata

  • Download URL: imagen_sdk-0.1.2-py3-none-any.whl
  • Upload date:
  • Size: 50.4 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.2-py3-none-any.whl
Algorithm Hash digest
SHA256 af320bde4f7cca26fd64b0c3c2d5e71a35bf571595f6eaf240d47a66a38e69aa
MD5 0ea934abe728652ab647451eed890f4e
BLAKE2b-256 edd828b1ad23f68b407cfc19f0efa6b464b9f3ffe2e7051476d8e9d1bc9685d6

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