Skip to main content
Ce guide décrit les étapes que traverse une sandbox, de sa création à son arrêt : les états par lesquels elle passe, comment la démarrer et attendre qu’elle soit prête, et comment l’arrêter proprement. Consultez-le lorsque vous devez choisir entre plusieurs modèles de création, maîtriser le moment du démarrage ou gérer l’arrêt de manière fiable dans votre code SDK.

Choisir l’authentification

Ces exemples s’exécutent sur une capacité sans serveur, sauf si une section indique CKS. Choisissez l’identifiant d’authentification du compte propriétaire de vos Sandbox. Pour obtenir une clé ou un jeton, consultez Choisir et obtenir des identifiants d’authentification. Exécutez les commandes d’installation dans un environnement virtuel Python actif. Enregistrez le code Python de l’onglet correspondant à votre identifiant d’authentification sous le nom sandbox_auth.py, dans le même répertoire que les scripts Python que vous exécutez à partir de cette page. Ce fichier stocke le mode d’authentification choisi, et non votre identifiant d’authentification. Les exemples importent AUTH depuis ce fichier et le transmettent explicitement à chaque nouvelle sandbox ou session.
Utilisez votre clé API Forge via la stratégie d’authentification W&B du SDK :
sandbox_auth.py
Pour un placement sur CKS, choisissez le jeton CoreWeave, activez un exécuteur et définissez placement_mode="cks" lors de la création de la sandbox ou dans SandboxDefaults. Créer une session avec auth=AUTH authentifie également les Sandbox qui lui appartiennent. Utilisez le même identifiant d’authentification pour vous reconnecter à des Sandbox, les lister ou les nettoyer.

États du cycle de vie

Chaque sandbox passe par une succession d’états au cours de son démarrage, de son exécution et de son arrêt. Le SDK représente ces états sous forme de valeurs SandboxStatus. PENDING et CREATING sont transitoires. Le SDK poursuit automatiquement l’interrogation pendant ces états. TERMINATING est un état transitoire du backend que wait_until_complete() et stop().result() font évoluer jusqu’à un état terminal. RUNNING est l’état opérationnel stable. COMPLETED et FAILED sont terminaux. Lors de l’interrogation, le SDK convertit UNSPECIFIED en COMPLETED. Vous pouvez déclencher un flux de travail lorsqu’une sandbox est créée, se termine ou échoue. Pour cela, créez une automatisation de changement de statut de sandbox dans le projet Weights & Biases de la sandbox. Vous pouvez par exemple publier un message dans un canal Slack ou appeler un webhook.

Modèles de création

Il existe deux façons de créer une sandbox, qui se distinguent par le moment où la RPC de démarrage est déclenchée. Les sections suivantes décrivent chaque modèle et indiquent dans quels cas le choisir.

Sandbox.run() : démarrage immédiat

Sandbox.run() crée une sandbox et appelle start().result() en interne, puis reste bloqué jusqu’à ce que le backend accepte la requête :
Le premier argument positionnel est la commande ; les suivants sont ses arguments :
Sandbox.run() prend la commande et ses arguments sous forme de chaînes de caractères, passées en arguments positionnels variadiques. Cette méthode n’accepte ni command ni args comme arguments nommés.

session.sandbox() : démarrage différé

session.sandbox() crée un objet sandbox sans effectuer le moindre appel réseau. Le RPC de démarrage se déclenche à la première utilisation :

Durée de vie de la commande principale

La commande transmise à run() ou à session.sandbox() constitue le processus principal de la sandbox. Ce qui se passe lorsqu’elle se termine dépend de son statut de sortie :
  • Statut de sortie 0 : la sandbox passe à l’état COMPLETED.
  • Statut de sortie non nul : la plateforme redémarre le conteneur du processus principal. Une sandbox qui a déjà atteint l’état RUNNING reste à l’état RUNNING pendant les redémarrages ; sinon, elle reste à l’état CREATING. wait_until_complete() continue d’attendre pendant les redémarrages, dans la limite de son timeout.
  • Limite de redémarrages atteinte : si le processus principal continue de se terminer avec un statut non nul, la sandbox passe à l’état FAILED une fois la limite de redémarrages atteinte (actuellement six redémarrages).
Un processus principal qui se termine avec succès met fin à la sandbox :
Si vous devez exécuter une commande courte et capturer sa sortie, utilisez exec() sur une sandbox de longue durée plutôt que d’en faire le processus principal.

Démarrer un sandbox

Une fois l’objet sandbox créé, vous pouvez le démarrer explicitement ou laisser le SDK le démarrer automatiquement lors de sa première utilisation. Les sections suivantes décrivent ces deux approches, ainsi que leur interaction avec les gestionnaires de contexte.

Démarrage explicite

start() envoie la RPC de démarrage et renvoie un OperationRef[None] :
C’est utile lorsque vous souhaitez contrôler le moment du démarrage ou traiter les erreurs de démarrage séparément des erreurs d’opération.

Démarrage automatique

La plupart des opérations démarrent automatiquement la sandbox si elle n’a pas encore été démarrée. Dans le cas le plus courant, il vous suffit de créer une sandbox et de commencer à l’utiliser.

Gestionnaires de contexte et démarrage

Les gestionnaires de contexte (with/async with) appellent start() à l’entrée, mais n’appellent pas wait(). Pour vérifier le statut de démarrage avant votre première opération, appelez wait() et consultez status :
En pratique, cela a rarement d’importance, car exec() attend en interne l’état RUNNING. Un appel explicite à wait() est utile lorsque vous souhaitez distinguer les échecs au démarrage des échecs d’opération.

Attendre une sandbox

Le SDK fournit des méthodes d’attente permettant d’inspecter le statut de démarrage ou d’attendre que la commande principale se termine. Les sections suivantes décrivent chaque méthode et expliquent le lien entre les délais d’expiration de démarrage et ceux des opérations.

wait() : attendre le statut de démarrage

wait() interroge l’état de la sandbox pendant les états de démarrage tels que PENDING et CREATING. Par exemple, il peut rendre la main lorsque la sandbox est à l’état RUNNING ou TERMINATING, ou une fois qu’elle s’est terminée avec succès :
L’interrogation applique un backoff exponentiel : elle commence avec des intervalles de 0,2 s, multipliés par 1,5 à chaque tentative, avec un plafond de 2,0 s. wait() renvoie l’objet sandbox. Vérifiez son status avant d’appeler une opération qui nécessite une sandbox en cours d’exécution. Un retour normal ne garantit pas que la sandbox soit à l’état RUNNING. Si la sandbox atteint un état terminal pendant le démarrage, wait() le gère ainsi :

wait_until_complete() : bloquer jusqu’à un état terminal

wait_until_complete() bloque jusqu’à ce que la sandbox atteigne un état terminal, en continuant automatiquement d’interroger son état pendant la phase TERMINATING. Utilisez cette méthode pour les Sandbox dont la commande principale effectue le travail :
Le paramètre raise_on_termination, défini sur True par défaut, détermine si wait_until_complete() lève SandboxTerminatedError lorsque ce client a appelé stop() ou qu’un backend hérité signale TERMINATED. Les arrêts externes signalés comme COMPLETED ne lèvent pas cette erreur, car la réponse ne permet pas de les distinguer d’un achèvement normal. En revanche, une sandbox qui atteint sa durée de vie maximale se termine à l’état FAILED, et wait_until_complete() lève alors SandboxFailedError.

Phases des délais d’expiration

Le temps d’attente au démarrage et les délais d’expiration des opérations sont deux phases distinctes, toutes deux bornées par la durée de vie maximale de la sandbox :
  • Attente de démarrage : temps passé à attendre le démarrage ou un état terminal anticipé. Contrôlée par le paramètre timeout de wait().
  • Attente d’achèvement : temps passé à attendre un état terminal, y compris la fin du démarrage, l’exécution, les éventuels redémarrages et l’arrêt. Contrôlée par le paramètre timeout de wait_until_complete().
  • Délai d’expiration des opérations : durée allouée à chaque exécution, lecture ou écriture. Contrôlé par timeout_seconds sur exec(), ou par request_timeout_seconds dans SandboxDefaults. N’inclut pas l’attente de démarrage.
  • Durée de vie maximale : durée totale (temps réel) pendant laquelle la sandbox peut exister, comptée à partir du démarrage, attente de démarrage comprise. Contrôlée par max_lifetime_seconds. Si vous ne la définissez pas, la valeur par défaut de la politique de l’exécuteur s’applique ; à défaut de valeur par défaut positive, la plateforme applique une valeur de repli de 10 minutes.
Les délais d’attente de démarrage et d’achèvement, ainsi que les délais d’expiration des opérations, limitent la durée d’attente du client, mais laissent la sandbox s’exécuter lorsqu’ils expirent. La durée de vie maximale limite la sandbox elle-même : à son expiration, la plateforme met fin à la sandbox et toute opération en cours échoue en même temps. Attribuez à max_lifetime_seconds une valeur largement supérieure à la durée totale de travail prévue. Vous ne pouvez plus la modifier une fois la sandbox démarrée. Pour découvrir les paramètres de délai d’expiration et leurs interactions, consultez Délais d’expiration. Pour la limite de 30 jours et des exemples de configuration pour sans serveur et CKS, consultez Exécuter des Sandbox de longue durée.

Opérations et cycle de vie

Les opérations telles que exec(), read_file() et write_file() démarrent automatiquement la sandbox si nécessaire, puis attendent l’état RUNNING avant de continuer :
Le délai d’expiration de l’opération (timeout_seconds) ne s’applique qu’une fois la sandbox à l’état RUNNING. Le temps de démarrage n’est pas pris en compte.

Arrêter une sandbox et fin de vie

Cette section explique comment arrêter une sandbox, ce qui se passe après son arrêt et quand utiliser stop() plutôt que delete().

stop()

stop() envoie une requête d’arrêt et renvoie OperationRef[None]. Le sandbox passe par l’état TERMINATING (drainage pendant le délai de grâce) avant d’atteindre un état terminal. L’OperationRef renvoyé est résolu lorsque le backend confirme l’état terminal, et non simplement lorsque l’appel RPC d’arrêt aboutit :
Paramètres : L’instantané à l’arrêt requiert une sandbox démarrée avec un montage file_system_snapshot, au sein d’une organisation pour laquelle les File System Snapshots (FSS) sont activés. Seul ce montage est capturé, et non l’intégralité du système de fichiers de la sandbox. Pour la configuration, voir Instantanés du système de fichiers.
stop() gère les démarrages en cours : si un démarrage est encore en cours de traitement, la méthode attend qu’il se termine avant de procéder à l’arrêt. Les appels simultanés à stop() sans option partagent une seule opération d’arrêt ; les appels répétés sans option n’émettent pas de RPC d’arrêt en double. Un appel avec snapshot_on_stop=True lève SnapshotOnStopConflictError s’il doit rejoindre ou observer un arrêt qui ne capture pas d’instantané. Demandez la capture d’un instantané à l’arrêt avant le début d’un arrêt sans option.

Comportement après l’arrêt

Une fois stop() appelé, la sandbox passe par l’état TERMINATING (état de drainage pendant le délai de grâce) puis atteint un état terminal (COMPLETED ou FAILED). Dès que stop() a été appelé, la sandbox devient inutilisable. Toute opération ultérieure lève SandboxNotRunningError :
La propriété status est mise en cache lors du dernier appel d’API. Pour obtenir des données à jour avant l’arrêt, utilisez get_status() :

Sortie du gestionnaire de contexte

Les gestionnaires de contexte appellent automatiquement stop() à leur sortie :
Si une exception est en cours de propagation, le gestionnaire de contexte ignore les erreurs d’arrêt afin de ne pas masquer l’exception d’origine.

stop() ou delete()

Utilisez stop() pour les Sandbox que vous êtes en train d’utiliser. Utilisez delete() pour nettoyer les Sandbox trouvées via Sandbox.list() ou Sandbox.from_id() :
Voir le guide des modèles de nettoyage pour connaître les stratégies de gestion des ressources orphelines et de nettoyage par lots.

Fonctionnement interne

Le SDK exécute toutes les opérations gRPC sur un thread démon en arrière-plan, doté de sa propre boucle d’événements asyncio. Cette conception a les conséquences suivantes :
  • L’API synchrone (.result()) bloque le thread appelant pendant que la boucle en arrière-plan gère l’appel réseau.
  • L’API asynchrone (await) s’appuie sur cette même boucle en arrière-plan : les deux modèles reposent donc sur la même implémentation sous-jacente.
  • La boucle en arrière-plan démarre de manière différée, lors de la première utilisation. Les canaux gRPC sont eux aussi créés de manière différée.
  • Le démarrage automatique consiste à vérifier si sandbox_id vaut None avant chaque opération et, le cas échéant, à déclencher start().
  • À la fin du processus, les handlers de nettoyage (atexit + handlers de signaux) arrêtent tous les Sandbox des sessions enregistrées. Un second Ctrl+C pendant le nettoyage force l’arrêt immédiat.
Cette architecture évite les problèmes liés à l’utilisation de plusieurs boucles d’événements et fonctionne dans les notebooks Jupyter sans nest_asyncio. Pour connaître les modèles d’utilisation, consultez le guide comparant les modèles synchrone et asynchrone.

Schémas courants

Les exemples suivants illustrent des schémas de bout en bout qui combinent les étapes du cycle de vie décrites ci-dessus.

Exécution ponctuelle rapide

Exécutez une commande et récupérez le résultat. Le gestionnaire de contexte se charge du nettoyage :

Démarrage contrôlé

Distinguez les erreurs de démarrage des erreurs d’opération :

Sandbox de longue durée

Attendez la fin de l’exécution de la commande principale :
Récupérez les fichiers avant que la commande principale du sandbox ne se termine. Pour les charges de travail dont les résultats doivent être téléchargés, exécutez le traitement avec exec() dans un sandbox doté d’un processus principal de longue durée, puis lisez les fichiers avant de l’arrêter.

Reconnexion

Reconnectez-vous à une sandbox créée lors d’une session ou d’un processus précédent :

Lot parallèle avec une session

Créez de multiples Sandbox et attendez les résultats :
Dernière modification le 4 novembre 2026