La façon la plus simple d’automatiser la génération d’images à grande échelle sans gérer plusieurs API est de séparer le flux de travail du fournisseur de modèle. Placez chaque requête d’image dans une seule file, orientez chaque tâche vers un ID de modèle actuel et envoyez les requêtes compatibles via une seule clé CometAPI et l’URL de base compatible OpenAI https://api.cometapi.com/v1.
Ce tutoriel construit ce pipeline en Python. Il accepte des tâches produit, publicité et contenu depuis une file JSON Lines ; choisit un modèle ; limite la concurrence ; réessaie les échecs transitoires ; stocke des résultats basés sur URL ou base64 ; et enregistre l’usage par tâche et un coût estimé. L’exemple conserve ces éléments essentiels de production dans un bloc compact afin que vous puissiez tester le flux de travail sans transformer l’article en référence de code.
Comment une API d’image unifiée simplifie la génération par lots
À la fin, le flux de travail ressemblera à ceci :
jobs.jsonl → bounded worker pool → CometAPI /v1/images/generations → object storage → manifest.jsonl
La couche de file et de stockage reste la vôtre. Changer de modèle d’image modifie la valeur model, pas le système d’authentification ni la route principale. C’est l’avantage pratique d’une API d’image unifiée : le choix du modèle devient une décision de routage au sein d’un seul pipeline au lieu d’une intégration par fournisseur.
De quoi avez-vous besoin pour automatiser la génération d’images ?
Vous avez besoin de Python 3.10 ou version ultérieure, du paquet requests, d’une clé CometAPI, d’un emplacement de sortie accessible en écriture et d’au moins un ID de modèle d’image actuel.
Installez l’unique dépendance :
pip install requests
Définissez votre clé côté serveur, jamais dans du code navigateur ou un dépôt :
export COMETAPI_KEY="your-key"
L’URL de base est https://api.cometapi.com/v1, et les tâches texte‑vers‑image compatibles utilisent POST /images/generations. Avant un déploiement, vérifiez chaque modèle dans le catalogue de modèles en direct ; le catalogue renvoie l’ID actuel, l’endpoint pris en charge, les fonctionnalités et les métadonnées de tarification sans exiger d’en-tête d’autorisation.
Au 20 août 2026, le catalogue en direct listait ces deux routes utiles :
| Charge de travail | ID du modèle | Pourquoi il convient |
|---|---|---|
| Images produit avec paramètres de sortie contrôlés | gpt-image-2 | Renvoie les données d’usage et un contenu image base64 sur la route compatible OpenAI |
| Concepts pub et contenu à haut volume | doubao-seedream-4-5-251128 | Utilise la même route de génération et est listé avec une tarification par requête |
Ce tableau est un point de départ, pas une affirmation que les modèles ont des capacités identiques. La taille, la qualité, le format, la prise en charge d’images de référence et le comportement de réponse restent spécifiques à chaque modèle. Consultez l’enregistrement du modèle et sa documentation liée avant de passer des paramètres optionnels.
Comment construire un flux de génération d’images par lots en Python
1. Donnez à chaque tâche un ID durable
Utilisez un objet JSON par ligne afin qu’une file, une exportation de base de données ou une tâche de feuille de calcul puisse alimenter le même worker :
{"id":"sku-1001","kind":"product","prompt":"Studio product photo of a ceramic coffee dripper on a warm neutral background"}
{"id":"campaign-204","kind":"ad","prompt":"Editorial summer travel image, vivid natural light, wide composition, no text"}
{"id":"blog-088","kind":"content","prompt":"Minimal illustration of a developer automating a creative workflow, no text"}
L’ID devient le nom de fichier de sortie et la clé du manifeste. En production, utilisez‑le comme clé d’idempotence et ignorez les IDs déjà marqués comme réussis avant de retraiter une file.
2. Orientez par type de tâche, puis validez via le catalogue en direct
L’exemple mappe le travail produit vers gpt-image-2 et le travail pub ou contenu vers doubao-seedream-4-5-251128. Une tâche peut remplacer ce choix avec son propre champ model. Au démarrage, le worker télécharge le catalogue public et rejette un ID qui n’est plus listé.
C’est plus sûr que de coder en dur un SDK spécifique au fournisseur dans toute l’application. Vous pouvez changer une route dans un seul mapping après avoir évalué la qualité, la latence et le prix pour vos propres invites.
3. Limitez la concurrence plutôt que de lancer tout le lot
Le worker commence avec quatre requêtes concurrentes. Ce nombre est un réglage d’application conservateur, pas une limite de service universelle. Mesurez la latence et les réponses 429 pour votre compte, puis augmentez ou diminuez MAX_WORKERS de façon délibérée.
Seules les réponses 408, 429 et 5xx sont réessayées avec backoff exponentiel et jitter. Les erreurs d’authentification, les IDs de modèle invalides et les paramètres non pris en charge échouent immédiatement, car réessayer la même mauvaise requête ne fait qu’ajouter du délai.
4. Normalisez le résultat avant stockage
Les modèles d’image ne renvoient pas toujours le même conteneur. La réponse GPT Image documentée contient data[0].b64_json ; d’autres modèles compatibles peuvent renvoyer data[0].url. Le worker gère les deux, écrit l’image dans un fichier temporaire et la renomme uniquement après la réussite du téléchargement ou du décodage.
En production, remplacez le répertoire local output/ par S3, R2, GCS ou un autre stockage d’objets. Ne considérez pas une URL hébergée par un fournisseur comme un stockage permanent, sauf si sa politique de rétention l’indique explicitement.
5. Enregistrez l’usage, les tentatives et le coût estimé
Chaque résultat devient une ligne de manifeste compacte avec l’ID de tâche, le modèle, le chemin sauvegardé, le statut et le coût USD estimé lorsque le catalogue en direct fournit suffisamment de données de tarification. Les tâches échouées conservent l’erreur au lieu de disparaître du lot.
Script Python complet pour la génération d’images par lots
Enregistrez ce qui suit sous batch_image_pipeline.py, placez la file à côté sous jobs.jsonl et exécutez python3 batch_image_pipeline.py.
import base64, json, os, random, time
from concurrent.futures import ThreadPoolExecutor
from pathlib import Path
import requests
BASE_URL = "https://api.cometapi.com/v1"
KEY = os.environ["COMETAPI_KEY"]
WORKERS = int(os.getenv("MAX_WORKERS", "4"))
OUT = Path("output")
ROUTES = {
"product": "gpt-image-2",
"ad": "doubao-seedream-4-5-251128",
"content": "doubao-seedream-4-5-251128",
}
catalog = requests.get("https://api.cometapi.com/api/models", timeout=30)
catalog.raise_for_status()
CATALOG = {model["id"]: model for model in catalog.json()["data"]}
def generate(job):
model = job.get("model", ROUTES[job["kind"]])
if model not in CATALOG:
raise ValueError(f"Unknown model: {model}")
payload = {"model": model, "prompt": job["prompt"], "n": 1}
if model == "gpt-image-2":
payload.update(quality="low", size="1024x1024", output_format="jpeg")
for attempt in range(4):
response = requests.post(
f"{BASE_URL}/images/generations",
headers={"Authorization": f"Bearer {KEY}"},
json=payload,
timeout=180,
)
if response.status_code not in {408, 429} and response.status_code < 500:
break
time.sleep(2**attempt + random.random())
response.raise_for_status()
body = response.json()
item = body["data"][0]
if item.get("b64_json"):
data = base64.b64decode(item["b64_json"])
extension = body.get("output_format", "png")
else:
download = requests.get(item["url"], timeout=120)
download.raise_for_status()
data = download.content
extension = {"image/png": "png", "image/webp": "webp"}.get(
download.headers.get("content-type"), "jpg"
)
path = OUT / f"{job['id']}.{extension}"
path.write_bytes(data)
price, usage = CATALOG[model].get("pricing") or {}, body.get("usage", {})
cost = price.get("per_request")
if cost is None and price.get("input") is not None:
cost = (usage.get("input_tokens", 0) * price["input"] +
usage.get("output_tokens", 0) * price["output"]) / 1_000_000
return {"id": job["id"], "model": model, "path": str(path),
"estimated_usd": cost * price.get("ratio", 1) if cost is not None else None}
def safe_generate(job):
try:
return {"status": "success", **generate(job)}
except Exception as error:
return {"id": job["id"], "status": "failed", "error": str(error)}
OUT.mkdir(exist_ok=True)
jobs = [json.loads(line) for line in Path("jobs.jsonl").read_text().splitlines() if line]
with ThreadPoolExecutor(max_workers=WORKERS) as pool:
results = list(pool.map(safe_generate, jobs))
with (OUT / "manifest.jsonl").open("w") as manifest:
manifest.writelines(json.dumps(result) + "\n" for result in results)
Le script utilise le catalogue actuel au moment de l’exécution, tandis que les deux mappages de secours sont des exemples vérifiés au 20 août 2026. Revalidez‑les avant de publier ou de déployer le code à une autre date.
Comment tester le flux de génération d’images par lots
Commencez avec une tâche et un worker :
MAX_WORKERS=1 python3 batch_image_pipeline.py
Une réponse GPT Image réussie suit cette structure :
{
"created": 1776841943,
"output_format": "jpeg",
"quality": "low",
"size": "1024x1024",
"usage": {
"input_tokens": 16,
"output_tokens": 208,
"total_tokens": 224
},
"data": [{"b64_json": "<base64-image-data>"}]
}
Le worker décode l’image, écrit output/<job-id>.jpeg et ajoute une ligne de succès à output/manifest.jsonl. Si un modèle renvoie une URL à la place, le worker la télécharge et stocke le chemin local dans le même format de manifeste.
Le code a été vérifié syntaxiquement en local. Un appel de génération réel nécessite toujours votre clé CometAPI ; lancez donc le test « smoke » à une tâche avant d’augmenter la concurrence.
Combien coûte la génération d’images par lots ?
La tarification doit être horodatée car les tarifs des modèles évoluent. Au 20 août 2026, le catalogue de modèles CometAPI en direct renvoyait les champs de prix de base suivants et un ratio de facturation 0.8 :
gpt-image-2: 5 $ par 1 M de tokens d’entrée et 30 $ par 1 M de tokens de sortie ; l’application du ratio indiqué donne des taux effectifs de 4 $ et 24 $ par 1 M de tokens.doubao-seedream-4-5-251128: 0,04 $ par requête ; l’application du ratio indiqué donne 0,032 $ par requête.
Le guide de tarification CometAPI explique la facturation basée sur les tokens pour les modèles avec tarification officielle et la facturation par appel pour les modèles tarifés par requête. Le script lit le catalogue à l’exécution et utilise la même règle :
token cost = ratio × (input tokens × input rate + output tokens × output rate) / 1,000,000
request cost = ratio × per-request price
Par exemple, la réponse GPT Image documentée ci‑dessus indique 16 tokens d’entrée et 208 tokens de sortie. En utilisant les valeurs du catalogue du 20 août, ce résultat illustratif est estimé à environ 0,005056 $. Le total réel varie selon le modèle, la qualité, la taille, l’invite, les réessais et l’usage de la réponse. Considérez la réponse API et le tableau de bord d’usage du compte comme la référence de facturation, pas une hypothèse fixe par image.
Prévoyez aussi du budget pour le travail infructueux. Un réessai après un délai d’attente non confirmé peut produire un second résultat facturable, et une image techniquement réussie qui échoue à l’examen consomme tout de même du budget. Suivez à la fois le coût API et le taux d’acceptation :
effective cost per accepted image = total batch spend / approved images
Erreurs courantes des API de génération d’images et comment les corriger
| Symptôme | Cause probable | Correctif |
|---|---|---|
| 401 | Clé manquante ou invalide | Vérifiez la variable serveur COMETAPI_KEY |
| 400 | Modèle invalide ou option non prise en charge | Recontrôlez le catalogue en direct et retirez les champs spécifiques au modèle |
| 429 | Trop de concurrence | Abaissez MAX_WORKERS et conservez le backoff exponentiel |
| 5xx répétés | Panne amont temporaire | Réessayez avec une limite, puis déplacez la tâche en DLQ |
| Aucune image sauvegardée | La réponse utilisait un autre conteneur | Inspectez data[0] et prenez en charge b64_json ou url |
| Dépense doublée | La tâche a été rejouée après un échec partiel | Utilisez des IDs durables et accusez réception après stockage |
Ne réessayez pas toutes les erreurs. Une requête 400 permanente restera invalide, tandis qu’une boucle de réessais illimitée sur 429 peut transformer un pic de trafic en arriéré.
Bonnes pratiques pour la production à grande échelle
Passez de JSON Lines à une file durable lorsque plusieurs workers sont impliqués. Définissez un délai de visibilité plus long que le temps de génération maximal, accusez réception d’une tâche uniquement après que l’image et le manifeste sont stockés et envoyez les tâches épuisées vers une dead‑letter queue pour examen.
Conservez les contrôles optionnels dans une configuration spécifique au modèle. Une charge utile partagée ne devrait contenir que des champs communs tels que model, prompt et n: 1 ; ajoutez quality, size ou output_format uniquement après que la documentation du modèle sélectionné les confirme. Si vous ajoutez un routage de secours, choisissez un modèle qui prend en charge la même tâche et reconstruisez la charge utile pour ce modèle au lieu de rejouer à l’aveugle des options spécifiques au fournisseur.
Stockez la clé API dans un gestionnaire de secrets, restreignez l’entrée des invites, scannez les ressources générées selon votre politique et gardez les URLs fournisseur hors des enregistrements produits à long terme. Journalisez l’ID de tâche, l’ID du modèle, la latence, les tentatives, l’usage, le chemin de stockage, le résultat de revue et la date d’instantané du catalogue. Ces champs vous permettent de comparer les modèles par coût d’image acceptée plutôt que par prix affiché.
Enfin, définissez des garde‑fous budgétaires : une taille maximale de lot, une limite de réessais par tâche, une alerte de dépense quotidienne et une condition d’arrêt quand le taux d’approbation chute. Accélérer une mauvaise invite n’est pas une optimisation.
FAQ sur l’automatisation de la génération d’images à l’échelle
Quelle est la façon la plus simple d’automatiser la génération d’images à grande échelle sans gérer plusieurs API ?
Utilisez un seul flux de file et de stockage, puis envoyez les requêtes d’image compatibles via une seule clé CometAPI et https://api.cometapi.com/v1/images/generations. Changez l’ID du modèle dans votre couche de routage au lieu de maintenir une authentification et des SDK par fournisseur.
Puis‑je envoyer une requête et demander à plusieurs modèles d’image de générer en même temps ?
L’exemple envoie un modèle par tâche. Le fan‑out est un flux d’application : dupliquez une tâche avec des IDs et des valeurs de modèle distincts, puis comparez les sorties stockées. Cela maintient le coût et le statut de revue attribuables à chaque modèle.
Quelle concurrence dois‑je utiliser ?
Il n’y a pas de nombre universel pour tous les comptes et modèles. Commencez avec un petit pool borné comme quatre workers, surveillez la latence et les réponses 429, puis ajustez à partir des données.
Dois‑je stocker l’URL renvoyée ou l’image elle‑même ?
Stockez l’image dans votre propre stockage d’objets. Une URL renvoyée peut être temporaire, tandis que les modèles GPT Image peuvent renvoyer un contenu base64 plutôt qu’une URL.
Comment choisir le modèle le moins cher ?
Calculez le coût par image acceptée, pas seulement le prix par appel. Incluez les frais par token ou par requête, les réessais, les téléchargements échoués, les ressources rejetées, le post‑traitement et la revue humaine. Recontrôlez le catalogue de modèles en direct le jour où vous publiez ou déployez.
Où vérifier l’endpoint et le format de réponse ?
Utilisez le guide de démarrage CometAPI, la documentation du catalogue de modèles, la référence de génération d’images et le guide de tarification.