File size: 3,592 Bytes
6494c95 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 | """Generate one real image and print the latency and the estimated cost.
uv run python -m scripts.try_image
uv run python -m scripts.try_image --model detailed --aspect landscape --moderate
uv run python -m scripts.try_image "a cat wearing a space helmet"
Needs the image backend's key (HF_TOKEN for `image_backend: hf`) in the environment or in the
.env file one folder above the repo. Costs real money (a few cents); run it locally, never in CI.
The image goes to a temporary PNG file, and the path is printed. The prompt is not moderated here:
use a harmless one. `--moderate` also sends the image to the OpenAI image moderation.
"""
from __future__ import annotations
import argparse
import asyncio
import os
import sys
import tempfile
from pathlib import Path
from src.config import load_env_file, load_settings
from src.errors import AppError
from src.logging_setup import configure_logging
from src.providers.base import ImageRequest
from src.providers.factory import build_image, build_moderator
DEFAULT_PROMPT = "a friendly robot painting a rainbow, colourful children's book illustration"
async def main() -> int:
parser = argparse.ArgumentParser(description=__doc__.splitlines()[0])
parser.add_argument("prompt", nargs="?", default=DEFAULT_PROMPT)
parser.add_argument("--model", help="image model key from config/models.yaml")
parser.add_argument("--aspect", choices=["square", "landscape", "portrait"], default="square")
parser.add_argument("--moderate", action="store_true", help="also moderate the image")
args = parser.parse_args()
sys.stdout.reconfigure(encoding="utf-8")
load_env_file()
settings = load_settings()
if settings.development_mode:
print("Development mode uses fakes; unset DEVELOPMENT_MODE to try the real service.")
return 2
key_name = "FAL_KEY" if settings.config.image_backend == "fal" else "HF_TOKEN"
needed = [key_name] + (["OPENAI_API_KEY"] if args.moderate else [])
missing = [name for name in needed if not os.environ.get(name)]
if missing:
print(f"Missing: {', '.join(missing)} (set it in the shell or the .env file).")
return 2
model_key = args.model or settings.models.defaults.create_model
active = settings.active_image_models()
if model_key not in active:
print(f"Unknown or inactive model '{model_key}'. Active: {list(active)}")
return 2
model = settings.models.image_models[model_key]
print(f"Backend {settings.config.image_backend}, model {settings.model_id_for(model)}")
try:
result = await build_image(settings).generate(
ImageRequest(prompt=args.prompt, model_key=model_key, aspect=args.aspect)
)
except AppError as error:
print(f"Failed: {type(error).__name__} (see the log line above)")
return 1
with tempfile.NamedTemporaryFile(prefix="ai_image_lab_", suffix=".png", delete=False) as file:
file.write(result.image)
print(f"Latency {result.seconds:.1f} s, estimated cost ${result.est_cost:.3f}")
print(f"Image: {len(result.image) / 1024:.0f} KiB -> {Path(file.name)}")
if args.moderate:
try:
verdict = await build_moderator(settings).moderate_image(result.image)
except AppError as error:
print(f"Image moderation failed: {type(error).__name__}")
return 1
print(f"Image moderation: {'FLAGGED ' + str(verdict.code) if verdict.flagged else 'clean'}")
return 0
if __name__ == "__main__":
configure_logging()
raise SystemExit(asyncio.run(main()))
|