multi-model-image-gen
Unified Python library for image generation across OpenAI, fal.ai, Google (AI Studio + Vertex AI), and Higgsfield. One API, aisuite-style addressing, retry + fallback, async-first, plugin-extensible.
from image_gen import generate
result = generate(
prompt="a neon-lit Tokyo alley at night",
model="fal:flux/dev",
fallbacks=["openai", "higgsfield"],
output="out.png",
)
Supported models
Catalog of models known to the library (current as of 2026-04-17). Shorthands resolve to the provider-native model ID automatically. Any full model ID also works — unknown models just pass through without capability validation.
Single source of truth:
src/image_gen/providers/catalog.yaml. Add or update a model = edit that file, no Python changes.
OpenAI — GPT Image family
| Shorthand | Model ID | Seed | Neg. prompt | Notes |
|---|---|---|---|---|
gpt-image-1.5 |
gpt-image-1.5 |
– | – | Current SOTA — natively multimodal (text + image I/O). |
gpt-image-mini |
gpt-image-1-mini |
– | – | Cheapest tier when quality is secondary. |
gpt-image |
gpt-image-1 |
– | – | Legacy. Kept for back-compat. |
Pricing is token-based (text + image tokens) — see OpenAI's pricing page for current rates. The image API also supports dall-e-2 / dall-e-3 via full model IDs.
fal.ai — curated subset of 1000+ models
Any fal model works by full ID (generate(model="fal:fal-ai/sdxl/lightning", …)). The shorthands below cover the most common ones:
| Shorthand | Model ID | Seed | Neg. prompt | Cost / image |
|---|---|---|---|---|
flux2-pro |
fal-ai/flux-2-pro |
✓ | – | ~$0.03 / MP |
flux2-dev-turbo |
fal-ai/flux-2-dev-turbo |
✓ | – | ~$0.008 |
flux-pro |
fal-ai/flux-pro |
✓ | – | $0.050 |
flux |
fal-ai/flux/dev |
✓ | – | $0.025 |
flux-schnell |
fal-ai/flux/schnell |
✓ | – | $0.003 |
seedream / seedream-4.5 |
fal-ai/bytedance/seedream/v4.5/text-to-image |
✓ | ✓ | $0.040 |
ideogram |
fal-ai/ideogram/v3 |
✓ | ✓ | $0.030–0.090 |
recraft |
fal-ai/recraft-v3 |
✓ | – | $0.040 raster / $0.080 vector |
nb2-fal |
fal-ai/nano-banana-2 |
– | – | $0.080 |
nb-pro-fal |
fal-ai/nano-banana-pro |
– | – | $0.150 |
imagen4-fal |
fal-ai/imagen4/preview |
– | – | variable |
fal acts as a unified gateway — you can use Google's Nano Banana and Imagen through fal's billing + API instead of Google's own credentials, which is occasionally useful for multi-tenant apps.
Google — Nano Banana + Imagen (AI Studio or Vertex AI)
Two providers, each with independent auth:
| Provider | Env var | Auth method | Use case |
|---|---|---|---|
google |
GOOGLE_VERTEX_API_KEY |
Vertex AI (API key) | Railway / production |
google |
GOOGLE_CLOUD_PROJECT |
Vertex AI (ADC) | Local dev |
google-studio |
GOOGLE_GEMINI_API_KEY |
AI Studio | Gemini-only, no GCP project |
google |
GOOGLE_API_KEY + GOOGLE_GENAI_USE_VERTEXAI=True |
Vertex AI (API key) | Legacy / compat |
google |
GOOGLE_API_KEY alone |
AI Studio | Legacy / compat |
GOOGLE_VERTEX_API_KEY takes priority for the google provider — set it to use a Vertex-bound API key instead of ADC. Imagen models require Vertex. google-studio shorthands (nb2, nano-banana, nb-pro) also work via google-studio:model-id if you want them on AI Studio billing.
Nano Banana (Gemini Image) — three tiers, shared generate_content API surface:
| Shorthand | Model ID | Aliases | Description |
|---|---|---|---|
nb-pro |
gemini-3-pro-image-preview |
Nano Banana Pro | Best reasoning ("Thinking"), high-fidelity text, most expensive. |
nb2 |
gemini-3.1-flash-image-preview |
Nano Banana 2 | Fast, high-volume. Trades some compositional depth for speed. |
nano-banana |
gemini-2.5-flash-image |
original Nano Banana | Legacy speed/efficiency tier. |
Imagen 4 — three tiers:
| Shorthand | Model ID | Notes |
|---|---|---|
imagen4-ultra |
imagen-4.0-ultra-generate-001 |
Highest fidelity; supports 1K + 2K + 4K. |
imagen4 |
imagen-4.0-generate-001 |
Default Imagen 4. |
imagen4-fast |
imagen-4.0-fast-generate-001 |
Cheapest / fastest. |
All Google image models output includes a SynthID watermark.
Higgsfield — async-task platform (submit → poll → download)
Polling is built in via poll_until. Higgsfield also gives day-0 access to third-party video models.
Soul (photorealistic image generation):
| Shorthand | Model ID |
|---|---|
higgsfield-soul |
higgsfield-ai/soul/standard |
higgsfield-soul-pro |
higgsfield-ai/soul/pro |
DoP (image-to-video, three quality/speed tiers):
| Shorthand | Model ID |
|---|---|
higgsfield-dop |
higgsfield-ai/dop/lite |
higgsfield-dop-preview |
higgsfield-ai/dop/preview |
higgsfield-dop-turbo |
higgsfield-ai/dop/turbo |
Kling (video via Higgsfield platform):
| Shorthand | Model ID | Notes |
|---|---|---|
higgsfield-kling |
kling-video/v3.0/master/image-to-video |
Kling 3.0 — unified video + audio + images, multi-shot. |
higgsfield-kling-v2 |
kling-video/v2.1/pro/image-to-video |
Kling 2.1 Master. |
Other Higgsfield platform models (Sora 2, WAN 2.5, MiniMax Hailuo 02, Seedance Pro, etc.) work by passing their full ID: generate(model="higgsfield:sora-2/preview", …).
All models support
Aspect ratios 9:16, 16:9, 1:1. Resolutions 720p, 1080p. Capabilities beyond these are rejected pre-flight with UnsupportedCapabilityError — the SDK call is never made. Add a model, or update capabilities, by editing src/image_gen/providers/catalog.yaml — no Python changes needed.
Install
pip install git+https://github.com/oj-rivas/multi-model-image-gen.git
# or pinned:
pip install git+https://github.com/oj-rivas/multi-model-image-gen.git@v0.2.0
# or editable from local checkout:
pip install -e /path/to/multi-model-image-gen
# with Prometheus metrics:
pip install "multi-model-image-gen[metrics] @ git+…"
Credentials
Set only the keys for providers you'll actually call:
# OpenAI
OPENAI_API_KEY=sk-…
# fal.ai
FAL_KEY=…
# Google — Vertex AI (production / Railway)
GOOGLE_VERTEX_API_KEY=… # "google" provider → Vertex with API key
GOOGLE_GEMINI_API_KEY=… # "google-studio" provider → AI Studio
GOOGLE_CLOUD_PROJECT=your-gcp-project # required for Vertex (Imagen 4)
GOOGLE_CLOUD_LOCATION=us-central1 # default
# Google — local dev (ADC)
# GOOGLE_CLOUD_PROJECT=your-gcp-project # Vertex via gcloud auth application-default login
# Google — legacy single key
# GOOGLE_API_KEY=… # AI Studio, or Vertex with GOOGLE_GENAI_USE_VERTEXAI=True
# Higgsfield
HIGGSFIELD_API_KEY=…
HIGGSFIELD_API_SECRET=…
HIGGSFIELD_BASE_URL=https://platform.higgsfield.ai # default
The library does not load .env for you. Use python-dotenv or your framework's loader.
Addressing
Three ways to name a model:
| Form | Example | Provider chosen by |
|---|---|---|
provider:model |
"fal:flux/dev" |
explicit prefix |
| Bare shorthand | "flux" |
catalog |
| Bare full model ID | "higgsfield-ai/soul/standard" |
catalog → higgsfield default |
Unknown provider prefix raises ValueError. Unknown bare models route to higgsfield (which uses full IDs rather than shorthands).
Library usage
Sync
from image_gen import generate
result = generate(
prompt="a neon fox",
model="flux", # catalog → fal-ai/flux/dev
output="fox.png", # written when status == "completed"
aspect_ratio="9:16",
resolution="720p",
)
assert result.status == "completed"
print(result.request_id, result.cost_usd)
Async — for FastAPI / high-concurrency
import asyncio
from image_gen import generate_async
async def batch():
return await asyncio.gather(*[
generate_async(prompt=f"scene {i}", model="flux")
for i in range(10)
])
Fallback chains
result = generate(
prompt="…",
model="fal:flux/dev",
fallbacks=["openai", "higgsfield"], # tried in order on retry-exhausted failure
correlation_id="trace-42",
)
Direct provider client (bypass routing)
from image_gen import FalImageClient
with FalImageClient() as client:
result = client.generate_image(
prompt="cinematic forest",
model="fal-ai/flux/dev",
aspect_ratio="16:9",
num_inference_steps=40, # provider-specific kwarg
)
client.download(result.image_url, "forest.png")
Result shape
@dataclass
class GenerationResult:
request_id: str
status: str # "completed" | "failed" | "blocked"
image_bytes: bytes | None # inline payload (OpenAI, Google)
image_url: str | None # remote URL (fal, Higgsfield)
video_url: str | None # Higgsfield video models
cost_usd: float | None # populated from catalog when available
raw: dict | None # full provider response + correlation_id if set
Callers that pass output= to generate() don't need to touch this — bytes/URL are handled automatically.
CLI
image-gen -p "a neon fox" -m flux -o fox.png
image-gen -p "…" -m "openai:gpt-image-1" --aspect 16:9 --resolution 1080p -o wide.png
image-gen -p "…" -m "higgsfield:higgsfield-ai/soul/standard" -o h.png
FastAPI integration
from fastapi import FastAPI, HTTPException
from image_gen import generate_async, FallbackExhausted
app = FastAPI()
@app.post("/images")
async def gen(prompt: str, model: str = "flux", x_correlation_id: str | None = None):
try:
r = await generate_async(prompt=prompt, model=model, correlation_id=x_correlation_id)
except FallbackExhausted as e:
raise HTTPException(502, str(e))
if r.status == "blocked":
raise HTTPException(422, r.raw)
return {"url": r.image_url, "cost": r.cost_usd, "id": r.request_id}
Resilience
- Retry: tenacity-backed exponential backoff on
httpx.TimeoutException,ConnectError,ReadError, and HTTP429/500/502/503/504. Configurable viaIMAGE_GEN_RETRY_ATTEMPTS(default 3) andIMAGE_GEN_RETRY_MAX_WAIT(default 8s). Non-transient errors (ValueError, 4xx) are not retried. - Fallback:
Routeriterates[primary, *fallbacks]; each provider's retries run first, then the router moves on.FallbackExhaustedis raised if all fail, carrying the list of underlying exceptions. - Blocked content: NSFW / policy refusals return
status="blocked"instead of raising — never retried.
Observability
Every generate() / generate_async() call emits one structured log record image_gen.request with canonical fields:
request_id, provider, model, latency_ms, status, bytes_out,
cost_usd, retry_count, fallback_used, correlation_id
Set IMAGE_GEN_LOG_FORMAT=json for one-line JSON per request (Datadog / CloudWatch / Loki-friendly).
Install the optional [metrics] extra to expose Prometheus counters: image_gen_requests_total, image_gen_retries_total, image_gen_fallbacks_total, image_gen_cost_usd_total, and histogram image_gen_latency_seconds.
Extending — add a provider as a plugin
No fork needed. In your own package:
# runway_image_gen/__init__.py
from image_gen.providers.base import ImageProvider
class RunwayClient:
def generate_image(self, prompt, model, aspect_ratio, resolution, **kw): ...
def download(self, url, output_path): ...
def close(self): ...
# pyproject.toml
[project.entry-points."image_gen.providers"]
runway = "runway_image_gen:RunwayClient"
Then pip install your-package and generate(model="runway:gen-3") just works — entry-point discovery picks it up.
Also works at runtime:
from image_gen import register_provider
register_provider("custom", MyClientFactory)
generate(model="custom:foo")
A complete example lives in examples/runway_plugin/.
Layout
src/image_gen/
├── __init__.py # generate(), generate_async(), Router re-export
├── cli.py # image-gen CLI
├── config.py # lazy env readers
├── router.py # Router, FallbackExhausted
├── observability.py # StructuredLogger, JSONFormatter, correlation_id
├── metrics.py # Prometheus (optional, gated on import)
├── py.typed # PEP 561 marker
└── providers/
├── __init__.py # registry + plugin discovery (register_provider, get_provider)
├── base.py # ImageProvider Protocol (sync + async)
├── result.py # GenerationResult
├── catalog.yaml # SINGLE SOURCE OF TRUTH for models
├── catalog.py # ModelEntry, resolve, validate
├── _retry.py # @retry_policy, is_retryable
├── _poll.py # poll_until, poll_until_async
├── README.md # "how to add an async-task provider"
├── openai_images.py
├── fal_images.py
├── google_images.py # AI Studio + Vertex AI
└── higgsfield.py
examples/
├── runway_plugin/ # third-party plugin example
└── benchmark_concurrent.py # async concurrency demo
License
MIT
Metadata
Release files for multi-model-image-gen 0.2.3
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | Actions |
|---|---|---|---|---|
| multi_model_image_gen-0.2.3.tar.gz | 58.8 kB | Without provenance | Details for multi_model_image_gen-0.2.3.tar.gz |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Actions Reset |
|---|---|---|---|---|
| multi_model_image_gen-0.2.3-py3-none-any.whl | Python 3 | none | any | Details for multi_model_image_gen-0.2.3-py3-none-any.whl |
Total release size: 102.6 kB
Release files / multi_model_image_gen-0.2.3.tar.gz
| Download URL | multi_model_image_gen-0.2.3.tar.gz |
|---|---|
| Size | 58.8 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
9cc70895bb1baf74bf7e8289eb06800535445b35b0b937f43f7a43159d0f4c7d
|
|
BLAKE2b-256 checksum How to use checksums |
7c419e71b5b49939ec0a58e08ae458b6169b2efb93886fd1bfce527f625a8749
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.10.6
|
Release files / multi_model_image_gen-0.2.3-py3-none-any.whl
| Download URL | multi_model_image_gen-0.2.3-py3-none-any.whl |
|---|---|
| Size | 43.9 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
7d7620bd08b8b6371d304daf6fa2e3375f4497382be93518feb873b6802aa1c5
|
|
BLAKE2b-256 checksum How to use checksums |
177ebf6bd08012bd2dd4d15f6a9db7eec7220d1eaefec3914d85b42eb4505742
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.10.6
|
Security for multi-model-image-gen 0.2.3
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.