# Appeler une API de génération média depuis Python ou Go

> L'API WaveSpeed en Python avec le SDK officiel, puis en Go avec la seule bibliothèque standard, et les trois erreurs qui font payer une génération deux fois.


*Ou : quelques lignes de code, et les trois détails qui décident si vous payez une image ou deux.*

La réponse courte : avec le SDK officiel, une génération WaveSpeed tient en un appel, `wavespeed.run()` en Python ou `wavespeed.Run()` en Go. Sans SDK, il faut deux requêtes HTTP, l'une pour soumettre la tâche et l'autre pour récupérer le résultat, avec au moins deux secondes entre deux interrogations. Dans tous les cas, trois règles évitent de payer deux fois ou de perdre un fichier : ne jamais renvoyer une soumission à l'aveugle, fixer un délai d'attente réaliste, et télécharger le résultat avant sept jours. C'est le passage obligé pour brancher [une API d'images et de vidéos](/guides/gpu-cloud-ia/api-inference-media/) sur une vraie application.

Le fonctionnement est asynchrone, comme chez la plupart des API de génération. Une requête `POST` sur l'adresse du modèle crée une tâche et renvoie aussitôt son identifiant. Une requête `GET` sur l'adresse du résultat indique où en est la tâche : `created`, `processing`, puis `completed` avec l'adresse du fichier, ou `failed`. Tout le code d'intégration consiste à attendre proprement entre les deux, et [la documentation de soumission](https://wavespeed.ai/docs/submit-task) donne le format exact de chaque réponse.

J'écris ces lignes en connaissance de cause : les illustrations de ce guide sont produites par un petit outil en Go qui appelle WaveSpeed exactement de cette façon, avec un délai maximal de cinq minutes par image et une interrogation toutes les trois secondes. Il n'utilise pas le SDK, par habitude de n'importer que la bibliothèque standard, et le code qui suit en est une version réduite.

> **Pour qui** : un développeur Python ou Go qui veut ajouter la génération d'images ou de vidéos à son application sans installer de modèle.
>
> **À partir de** : 0,003 $ l'image avec Flux schnell, 0,0035 $ avec MiniMax Image-01, 0,15 $ le clip WAN 2.2 de cinq secondes en 480p, facturés à la génération.
>
> **Pour démarrer** : créer une clé sur WaveSpeed, la placer dans la variable `WAVESPEED_API_KEY`, et lancer l'un des deux exemples.

## WaveSpeed API en Python et en Go : deux intégrations complètes

En Python, le SDK officiel fait tout le travail d'attente. Il s'installe avec `pip install wavespeed` et lit la clé dans l'environnement :

```python
# La clé est lue dans la variable d'environnement WAVESPEED_API_KEY
import wavespeed

sortie = wavespeed.run(
    "wavespeed-ai/flux-schnell",
    {"prompt": "une lanterne de laiton sur une marche de pierre", "size": "1024*1024"},
    timeout=300.0,      # délai maximal d'attente, en secondes
    poll_interval=2.0,  # jamais plus souvent que toutes les deux secondes
)
print(sortie["outputs"][0])  # adresse du fichier, conservé sept jours au plus
```

En Go, le SDK existe aussi, `github.com/WaveSpeedAI/wavespeed-go`, mais la bibliothèque standard suffit, et elle montre ce qui se passe réellement :

```go
// Soumet une génération puis attend le résultat, sans dépendance externe
package main

import (
	"bytes"
	"encoding/json"
	"fmt"
	"net/http"
	"os"
	"time"
)

const base = "https://api.wavespeed.ai/api/v3"

type reponse struct {
	Data struct {
		ID      string   `json:"id"`
		Status  string   `json:"status"`
		Outputs []string `json:"outputs"`
		Error   string   `json:"error"`
	} `json:"data"`
}

func appel(methode, url string, corps []byte) (reponse, error) {
	var r reponse
	req, err := http.NewRequest(methode, url, bytes.NewReader(corps))
	if err != nil {
		return r, err
	}
	req.Header.Set("Authorization", "Bearer "+os.Getenv("WAVESPEED_API_KEY"))
	req.Header.Set("Content-Type", "application/json")
	resp, err := http.DefaultClient.Do(req)
	if err != nil {
		return r, err
	}
	defer resp.Body.Close()
	if resp.StatusCode != http.StatusOK {
		return r, fmt.Errorf("HTTP %d", resp.StatusCode)
	}
	return r, json.NewDecoder(resp.Body).Decode(&r)
}

func main() {
	corps, _ := json.Marshal(map[string]any{"prompt": "une lanterne de laiton", "size": "1024*1024"})

	// Soumission : envoyée une seule fois, jamais relancée automatiquement
	r, err := appel("POST", base+"/wavespeed-ai/flux-schnell", corps)
	if err != nil {
		fmt.Println("soumission :", err)
		return
	}
	id := r.Data.ID

	limite := time.Now().Add(5 * time.Minute)
	for time.Now().Before(limite) {
		time.Sleep(2 * time.Second)
		r, err = appel("GET", base+"/predictions/"+id+"/result", nil)
		if err != nil {
			continue // une lecture ratée se retente sans risque
		}
		switch r.Data.Status {
		case "completed":
			fmt.Println(r.Data.Outputs[0])
			return
		case "failed", "cancelled", "timeout":
			fmt.Println("échec :", r.Data.Error)
			return
		}
	}
	fmt.Println("délai dépassé, tâche à reprendre :", id)
}
```

Les trois règles annoncées se lisent dans ce code. La première concerne la soumission : elle n'est jamais relancée. [La documentation du SDK Python](https://wavespeed.ai/docs/python-sdk) l'explique très bien : une coupure réseau peut survenir après que le serveur a déjà créé la tâche, et renvoyer la requête en crée une seconde, facturée elle aussi. Les lectures du résultat, elles, se retentent sans risque. Méfiez-vous au passage de l'exemple du SDK Go, qui active trois relances de tâche : mettez-les à zéro tant que vous n'avez pas de raison précise de payer une tâche de remplacement.

La deuxième règle concerne le délai. Un délai trop court abandonne une tâche qui finira quand même, et sera facturée sans jamais être récupérée. Le pipeline vidéo de ce site en a fait l'expérience sur un autre fournisseur : sa boucle renonçait au bout de dix minutes, alors que certains jours la file d'attente retenait un clip neuf à dix minutes avant de le calculer. Le délai est passé à trente minutes. Comptez quelques minutes pour une image, une demi-heure pour une vidéo, et gardez l'identifiant de chaque tâche abandonnée pour la reprendre plus tard.

La troisième règle concerne le stockage : l'adresse renvoyée pointe vers le réseau de diffusion de WaveSpeed, qui conserve les fichiers sept jours au plus. Téléchargez le fichier dès la fin de la tâche et rangez-le chez vous. Si vous ne voulez pas de téléchargement du tout, le paramètre `enable_base64_output` renvoie le fichier encodé dans la réponse, au prix d'une réponse beaucoup plus lourde.

fal.ai et Replicate suivent exactement le même schéma, avec leurs propres clients. Chez fal.ai, `pip install fal-client` puis `fal_client.subscribe()` soumet la tâche à la file d'attente et attend le résultat ; la clé passe dans l'en-tête `Authorization: Key`, et non `Bearer`. Chez Replicate, `pip install replicate` puis `replicate.run()`, avec un client Go officiel, `replicate-go`. Une différence compte pour votre code : Replicate efface les fichiers de sortie une heure après une prédiction lancée par l'API, là où fal.ai garde les médias au moins sept jours. Passer d'une plateforme à l'autre revient surtout à changer l'adresse, l'en-tête et le nom des champs, pas l'architecture.

![Illustration : deux câbles de cuivre tressé branchés sur le flanc d'une machine lumineuse dans un atelier sombre, une fine lueur ambrée courant le long de chaque câble](/images/integrer-api-inference-python-go-connecteur.original.webp "Deux langages, un seul branchement : une requête pour lancer, une autre pour venir chercher le résultat.")

### Si vous voulez tester avant d'écrire du code

Deux requêtes à la main suffisent pour voir sortir une première image, avec le dollar d'essai. La démarche est décrite dans [la première génération par API](/guides/gpu-cloud-ia/api-inference-media/premiere-generation-api-media-credits/).

### Si vos générations durent plusieurs minutes

La boucle d'attente convient à une image. Pour une vidéo de plusieurs minutes, un webhook évite de garder un processus à interroger l'API, comme l'explique [recevoir le résultat par webhook](/guides/gpu-cloud-ia/api-inference-media/webhooks-polling-jobs-longs-api-media/).


---

Cette page contient des liens d'affiliation. Si tu souscris via ces liens, je peux toucher une commission sans coût supplémentaire pour toi. Mon avis reste indépendant et basé sur mon usage réel des outils que je recommande.


---

**Tarifs :** prix relevés le 27 septembre 2026 sur les sites officiels des fournisseurs, dans la devise qu'ils affichent : dollars américains pour les plateformes américaines, euros hors taxes pour les européennes. Les tarifs du GPU bougent souvent, et sur une place de marché chaque hôte fixe son prix : les montants cités peuvent avoir changé depuis cette date.

