SDK Python 2.0 : prise en charge d’asyncio et Python 3.12+
La version 2.0.0 de notre SDK Python, pytransloadit, ajoute
AsyncTransloadit, un client asyncio qui complète le client synchrone que vous utilisez
déjà. Elle porte aussi la version minimale de Python à 3.12.
Nous présentons ci-dessous les usages du client asynchrone et les points à vérifier avant de migrer
depuis la version 1.x.
Pourquoi utiliser un client asynchrone ?
Le client 1.x communique avec notre API via Requests, qui est bloquant. Dans une application FastAPI ou aiohttp, chaque appel à ce client bloque la boucle d’événements. Pendant qu’une requête attend qu’une Assembly se termine, les autres requêtes sur ce worker attendent aussi, sauf si vous déplacez vous-même l’appel vers un pool de threads.
AsyncTransloadit envoie ses appels API via aiohttp et consulte régulièrement l’état des
Assemblies avec asyncio.sleep. Vous pouvez ainsi attendre une Assembly avec
await, comme toute autre opération d’entrée-sortie. Cela facilite aussi
l’exécution simultanée de plusieurs Assemblies depuis un script ou un worker en arrière-plan.
Traiter des fichiers simultanément
Installez la version 2.0 avec Python 3.12 ou une version ultérieure :
python -m pip install --upgrade 'pytransloadit>=2,<3'
Ce script redimensionne trois photos en parallèle avec
🤖 /image/resize, en partageant un client et une session HTTP.
Il lit vos informations d’accès dans TRANSLOADIT_KEY et
TRANSLOADIT_SECRET :
import asyncio
import os
from transloadit.async_client import AsyncTransloadit
async def resize(client, path):
assembly = client.new_assembly()
thumb = {"use": ":original", "width": 400}
assembly.add_step("thumb", "/image/resize", thumb)
with open(path, "rb") as upload:
assembly.add_file(upload)
response = await assembly.create(wait=True, resumable=False)
if "error" in response.data:
raise RuntimeError(f"{path}: {response.data['error']}")
return response.data["results"]["thumb"][0]["ssl_url"]
async def main():
paths = ["chameleon.jpg", "prinsengracht.jpg", "desert.jpg"]
key = os.environ["TRANSLOADIT_KEY"]
secret = os.environ["TRANSLOADIT_SECRET"]
async with AsyncTransloadit(key, secret) as client:
urls = await asyncio.gather(*(resize(client, p) for p in paths))
print("\n".join(urls))
asyncio.run(main())
Téléchargez les photos d’exemple et exécutez le script :
for photo in chameleon prinsengracht desert; do
curl -fsSLo "$photo.jpg" \
"https://demos.transloadit.com/inputs/$photo.jpg"
done
python resize_many.py
Le script affiche une URL par miniature. Sur notre machine, les trois Assemblies (25 MB de photos) se sont terminées en environ 3 secondes, contre environ 8 secondes pour la même boucle avec le client synchrone.
wait=True rend la main une fois l’Assembly terminée. Les erreurs de l’API sont
toujours renvoyées dans la réponse, c’est pourquoi le script vérifie
error. resumable=False envoie chaque fichier dans la requête de
création. Pour les fichiers volumineux, conservez sa valeur par défaut,
True : les téléversements avec reprise passent par tus, que le SDK exécute
dans des threads de travail. La boucle d’événements reste ainsi réactive pendant leur téléversement.
L’utiliser dans FastAPI
Installez FastAPI, Uvicorn et l’analyseur multipart dont FastAPI a besoin pour les téléversements :
python -m pip install fastapi uvicorn python-multipart
Créez le client une seule fois par application et partagez-le entre les requêtes :
import os
from contextlib import asynccontextmanager
from fastapi import FastAPI, HTTPException, UploadFile
from transloadit.async_client import AsyncTransloadit
@asynccontextmanager
async def lifespan(app: FastAPI):
key = os.environ["TRANSLOADIT_KEY"]
secret = os.environ["TRANSLOADIT_SECRET"]
async with AsyncTransloadit(key, secret) as client:
app.state.transloadit = client
yield
app = FastAPI(lifespan=lifespan)
@app.post("/thumbnails")
async def create_thumbnail(file: UploadFile):
assembly = app.state.transloadit.new_assembly()
thumb = {"use": ":original", "width": 400}
assembly.add_step("thumb", "/image/resize", thumb)
assembly.add_file(file.file)
response = await assembly.create(wait=True, resumable=False)
thumbs = response.data.get("results", {}).get("thumb")
if "error" in response.data or not thumbs:
raise HTTPException(502, "Could not create a thumbnail")
return {"url": thumbs[0]["ssl_url"]}
uvicorn app:app
curl -fsSL -F file=@chameleon.jpg http://127.0.0.1:8000/thumbnails
Nous avons envoyé trois téléversements simultanément à ce point de terminaison, et un seul worker
Uvicorn a répondu aux trois en moins de 4 secondes. Attendre le résultat dans la requête convient
aux traitements rapides d’images. Pour la vidéo et les autres traitements longs, créez l’Assembly
sans wait=True et transmettez un notify_url à
new_assembly(), afin que Transloadit
appelle votre application une fois le traitement terminé.
Ce que couvre le client asynchrone
AsyncTransloadit reprend les fonctionnalités du client synchrone : créer, récupérer,
lister et annuler des Assemblies, gérer des Templates,
récupérer la facturation mensuelle et signer des URL du Smart CDN.
Utilisez await pour les méthodes qui accèdent au réseau.
new_assembly(), new_template() et get_signed_smart_cdn_url() restent
synchrones.
Utilisez le client avec async with, ou appelez await client.aclose()
quand vous avez terminé. Vous pouvez fournir votre propre session aiohttp avec
session=. Les transferts avec reprise n’utilisent toutefois pas cette session :
ses paramètres de proxy et de TLS ne s’appliquent donc pas à ces transferts. Configurez-les plutôt
via l’environnement de Requests.
Migrer depuis la version 1.x
Votre code synchrone continue de fonctionner : from transloadit import client et ses méthodes restent
inchangés dans la version 2.0. Voici les points à vérifier :
- Python 3.12 ou une version ultérieure. Mettez d’abord à niveau vos interpréteurs de
développement, de CI et de déploiement. Avec Python 3.9 à Python 3.11, pip continue d’installer la
version 1.0.4, la dernière version de la série 1.x. Fixez
pytransloadit<2pour rendre ce choix explicite. - Versions minimales des dépendances. La version 2.0 exige
requests>=2.33,<3eturllib3>=2.7,<3. Assouplissez les versions plus anciennes fixées dans vos contraintes et régénérez votre fichier de verrouillage. - Redirections. Les redirections HTTP vous sont renvoyées au lieu d’être suivies.
- Validation des entrées. Les URL de service invalides et les identifiants de Template vides
déclenchent
ValueError. - Templates. Lorsque vous combinez une option
templateavecadd_step(), fournissez la valeur detemplatesous forme de dictionnaire, et non de chaîne JSON. - Réponses. Une réponse non JSON place du texte ou des octets dans
Response.data, et un corps vide donne une chaîne vide. - Interrogation périodique. Avec
wait=True, l’épuisement des tentatives lors des vérifications d’état soumises à une limitation de débit déclencheAssemblyPollingError. L’Assembly peut encore être en cours : utilisez leassembly_urlde l’erreur pour consulter à nouveau son état ou l’annuler. - URL d’Assembly. Les requêtes de consultation d’état et d’annulation sont envoyées uniquement à des URL d’Assembly de confiance, et le client par défaut rejette les autres hôtes.
- Smart CDN. Les paramètres booléens sont signés sous la forme
trueetfalse, conformément à notre implémentation de référence Node.js. Les slugs de Workspace doivent être compatibles avec le DNS, etauth_key,expetsigsont des clés de requête réservées.
Le README et le journal des modifications de la version 2.0.0 contiennent toutes les notes de migration.
Commencer
python -m pip install --upgrade 'pytransloadit>=2,<3'
Retrouvez le paquet sur PyPI, des scripts synchrones et asynchrones exécutables dans le dossier des exemples, et la référence de l’API sur Read the Docs. Notre documentation du SDK Python présente les bases. Vous n’avez pas encore de compte ? Inscrivez-vous gratuitement pour pouvoir exécuter les exemples ci-dessus en quelques minutes. Avec le forfait gratuit Community, les images produites portent un filigrane ; notre FAQ explique pourquoi. Adressez vos questions ou problèmes liés à la migration au système de suivi des problèmes de python-sdk.
