> ## Documentation Index
> Fetch the complete documentation index at: https://docs.coreweave.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Fonctions distantes

> Exécutez des fonctions Python dans des sandboxes avec le décorateur function.

Ces exemples utilisent un jeton d’accès à l’API CoreWeave défini dans `CWSANDBOX_API_KEY`. Pour l’authentification par clé API Forge, voir [Premiers pas](/fr/products/sandboxes/get-started). Pour les exigences relatives à CKS, voir [Modes de placement](/fr/products/sandboxes/placement).

Ce guide présente le décorateur `@session.function()`, qui permet d’exécuter des fonctions Python dans des sandboxes. Il s’adresse aux développeurs qui souhaitent déporter des calculs Python ponctuels vers des environnements isolés sans avoir à gérer eux-mêmes le cycle de vie d’un sandbox. Il explique comment définir des fonctions distantes, quels types d’arguments et de valeurs de retour l’API prend en charge, et dans quels cas cette API est la plus adaptée.

<h2 id="overview">
  Aperçu
</h2>

L’API de décorateur de fonction vous permet d’exécuter des fonctions Python dans des conteneurs sandbox isolés. Utilisez-la pour exécuter à distance des traitements Python distincts tout en conservant un code appelant simple :

```python theme={"system"}
import cwsandbox
from cwsandbox import SandboxDefaults

with cwsandbox.Session(SandboxDefaults(container_image="python:3.11")) as session:
    @session.function()
    def compute(x: int, y: int) -> int:
        return x + y

    # Exécuter dans une sandbox
    result = compute.remote(2, 3).result()
    print(result)  # 5
```

<h2 id="basic-usage">
  Utilisation de base
</h2>

<h3 id="define-functions">
  Définir des fonctions
</h3>

Décorez les fonctions avec `@session.function()` :

```python theme={"system"}
@session.function()
def process_data(data: dict) -> dict:
    # Le code s’exécute dans la sandbox
    import pandas as pd
    df = pd.DataFrame(data)
    return {"mean": df["value"].mean()}
```

<h3 id="call-functions">
  Appeler des fonctions
</h3>

Appelez `.remote()` sur la fonction décorée pour l’exécuter dans le sandbox :

```python theme={"system"}
# Renvoie immédiatement un OperationRef
ref = compute.remote(2, 3)

# Attendre le résultat (appel bloquant)
result = ref.result()

# En une seule ligne
result = compute.remote(2, 3).result()
```

<h2 id="execution-methods">
  Méthodes d’exécution
</h2>

<h3 id="run-in-parallel-with-map">
  Exécuter en parallèle avec map()
</h3>

Exécutez sur plusieurs entrées :

```python theme={"system"}
@session.function()
def square(x: int) -> int:
    return x * x

# Exécuter pour chaque entrée
refs = square.map((x,) for x in range(10))

# Récupérer tous les résultats
from cwsandbox import results
all_results = results(refs)  # [0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
```

Avec des tuples pour des arguments multiples :

```python theme={"system"}
@session.function()
def add(x: int, y: int) -> int:
    return x + y

# Chaque tuple est dépaqueté en arguments
refs = add.map([(1, 2), (3, 4), (5, 6)])
all_results = results(refs)  # [3, 7, 11]
```

<h3 id="run-locally-with-local">
  Exécuter en local avec local()
</h3>

Exécutez le code en local, sans sandbox, ce qui est pratique pour les tests :

```python theme={"system"}
# Aucune sandbox n'est créée : exécution dans le processus courant
result = compute.local(2, 3)
print(result)  # 5
```

<h2 id="argument-and-return-types">
  Types des arguments et des valeurs de retour
</h2>

Les fonctions distantes transmettent les arguments et les valeurs de retour au format JSON. Ils doivent donc être sérialisables en JSON : dictionnaires, listes, chaînes de caractères, nombres, booléens et `None`.

```python theme={"system"}
@session.function()
def process(data: dict) -> dict:
    return {"result": data["value"] * 2}
```

Si vous transmettez un argument non représentable en JSON, l'appel lève une exception `TypeError` avant le démarrage de la sandbox :

```text title="Example output" theme={"system"}
TypeError: Function arguments are not JSON-serializable: Object of type ndarray is not JSON serializable
```

Une valeur de retour que JSON ne peut pas représenter provoque le même échec, avec le message `return value is not JSON-serializable`.

Les objets JSON n'acceptent que des clés de type string. Un dictionnaire dont les clés sont des entiers, des nombres à virgule flottante ou des booléens est rejeté plutôt que converti : ainsi, les types que reçoit votre fonction dans la sandbox correspondent à ceux que vous avez transmis.

Pour manipuler des tableaux NumPy, des DataFrames pandas ou des instances de classes personnalisées, convertissez-les en valeurs compatibles avec JSON avant d'appeler la fonction, puis reconstruisez-les à l'intérieur de celle-ci :

```python theme={"system"}
@session.function()
def array_mean(values: list[float]) -> float:
    from statistics import fmean
    return fmean(values)

result = array_mean.remote([1.0, 2.0, 3.0, 4.0, 5.0]).result()  # 3.0
```

Le client n’installe rien avant d’exécuter votre fonction. Toute bibliothèque importée par la fonction, comme NumPy, doit déjà être présente dans l’image de conteneur.

Si les données sont trop volumineuses pour être transmises en JSON, écrivez-les dans un stockage accessible depuis la sandbox et transmettez plutôt une référence. Voir [Opérations sur les fichiers](/fr/products/sandboxes/client/guides/file-operations).

<h2 id="closures-and-globals">
  Closures et variables globales
</h2>

<h3 id="closure-variables">
  Variables de closure
</h3>

Les fonctions capturent les variables de leur portée englobante :

```python theme={"system"}
multiplier = 10

@session.function()
def multiply(x: int) -> int:
    return x * multiplier  # Capture la variable 'multiplier'

result = multiply.remote(5).result()  # 50
```

<h3 id="global-variables">
  Variables globales
</h3>

Le décorateur sérialise avec la fonction les variables globales auxquelles elle fait référence :

```python theme={"system"}
CONFIG = {"threshold": 0.5}

@session.function()
def check_value(x: float) -> bool:
    return x > CONFIG["threshold"]

result = check_value.remote(0.7).result()  # True
```

Les variables de closure capturées et les variables globales sont transférées vers la sandbox au format JSON, tout comme les arguments et les valeurs de retour. Si une fonction capture une valeur non représentable en JSON, l'appel échoue pour cette raison, même si tous les arguments que vous transmettez sont valides.

<h2 id="container-image">
  Image de conteneur
</h2>

Remplacez l’image de conteneur pour certaines fonctions :

```python theme={"system"}
@session.function(container_image="pytorch/pytorch:latest")
def train_model(data: dict) -> dict:
    import torch
    # Code d'entraînement sur GPU
    return {"loss": 0.01}
```

<h2 id="error-handling">
  Gestion des erreurs
</h2>

Les exceptions levées par une fonction se propagent jusqu’à l’appelant :

```python theme={"system"}
@session.function()
def failing_function() -> None:
    raise ValueError("Something went wrong")

try:
    failing_function.remote().result()
except Exception as e:
    print(f"Function failed: {e}")
```

<h2 id="when-to-use-functions-compared-to-sandboxes">
  Quand utiliser les fonctions plutôt que les sandboxes
</h2>

Utilisez le tableau suivant pour déterminer laquelle de l’API du décorateur de fonction ou de l’API sandbox convient le mieux à votre charge de travail.

| Cas d’utilisation | API recommandée |
| - | - |
| Calcul Python simple | Décorateur de fonction |
| Map/reduce sur des données | Décorateur de fonction |
| Flux de travail interactif, commandes multiples | Sandbox |
| Sortie en diffusion en continu | Sandbox |
| Manipulation de fichiers | Sandbox |
| Processus de longue durée | Sandbox |

<h2 id="limitations">
  Limitations
</h2>

L’API de fonctions est volontairement simple. Pour les flux de travail complexes :

* **Nouvelles tentatives et backoff** : implémentez-les dans le code appelant.
* **Dépendances entre tâches et DAG** : utilisez un orchestrateur de flux de travail comme Airflow ou Prefect.
* **Ordonnancement complexe** : utilisez directement l’API de sandbox.

<h2 id="complete-example">
  Exemple complet
</h2>

L’exemple suivant réunit les concepts présentés dans ce guide. Il illustre l’exécution unique et l’exécution parallèle, ainsi qu’un calcul dont l’argument et la valeur de retour sont transmis au format JSON :

```python theme={"system"}
import cwsandbox
from cwsandbox import SandboxDefaults, results

defaults = SandboxDefaults(
    container_image="python:3.11",
    tags=("remote-functions-demo",),
)

with cwsandbox.Session(defaults=defaults) as session:
    @session.function()
    def square(x: int) -> int:
        return x * x

    # L’argument est une liste et le résultat un nombre à virgule flottante : tous deux sont donc sérialisables en JSON
    @session.function()
    def array_mean(values: list[float]) -> float:
        from statistics import fmean
        return fmean(values)

    # Exécution unique
    result = square.remote(7).result()
    print(f"7 squared: {result}")

    # Exécution en parallèle
    refs = square.map((x,) for x in range(5))
    all_results = results(refs)
    print(f"Squares: {all_results}")

    # Calcul compatible JSON
    mean = array_mean.remote([1.0, 2.0, 3.0, 4.0, 5.0]).result()
    print(f"Array mean: {mean}")
```
