> ## Documentation Index
> Fetch the complete documentation index at: https://private-7c7dfe99-trino-dialect.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Fonctions définies par l’utilisateur dans Cloud

> Ajoutez vos propres fonctions Python exécutables dans Cloud

export const BetaBadge = ({link, galaxyTrack, galaxyEvent}) => {
  if (link) {
    return <a href={link} target="_blank" rel="noopener noreferrer" className="betaBadge" onClick={galaxyTrack && galaxyEvent ? galaxyOnClick(galaxyEvent) : undefined}>
                <span>Beta</span>
            </a>;
  }
  return <a href="https://clickhouse.com/docs/reference/settings/beta-and-experimental-features#beta-features" className="betaBadge">
            <span>Fonctionnalité en bêta</span>
        </a>;
};

Les fonctions définies par l’utilisateur (UDF) permettent d’étendre le comportement de ClickHouse au-delà de ce que permettent les plus de mille [fonctions](/fr/reference/functions/regular-functions/overview) intégrées.

Dans ClickHouse Cloud, il existe plusieurs façons de créer et de gérer des fonctions définies par l’utilisateur :

1. À l’aide de SQL
2. À l’aide de l’UI et de votre propre code (Public Beta)
3. À l’aide de la [Cloud API](#manage-udfs-with-the-cloud-api) (Beta)
4. À l’aide de [Terraform](#manage-udfs-with-terraform) (alpha)

<div id="sql-udfs">
  ## Fonctions SQL définies par l’utilisateur
</div>

Les UDF SQL peuvent être créées à l’aide de l’instruction [`CREATE FUNCTION`](/fr/reference/statements/create/function) à partir d’une expression lambda.

Dans cet exemple, nous allons créer une simple fonction exécutable définie par l’utilisateur, `isBusinessHours`.
La fonction vérifiera si un timestamp donné correspond aux heures ouvrées habituelles et renverra true si c’est le cas, sinon false.

1. Connectez-vous à Cloud Console et ouvrez la console SQL
2. Écrivez la SQL query suivante pour créer la fonction `isBusinessHours` :

```sql theme={null}
CREATE FUNCTION isBusinessHours AS (ts) ->
toDayOfWeek(ts) BETWEEN 1 AND 5
AND toHour(ts) BETWEEN 9 AND 17;
```

3. Exécutez ce qui suit pour tester l’UDF que vous venez de créer :

```sql theme={null}
SELECT isBusinessHours('2026-03-20 10:00:00'::DateTime), isBusinessHours('2026-03-20 23:00:00'::DateTime);
```

Vous devriez obtenir le résultat suivant :

```response theme={null}
1   0
```

4. Vous pouvez utiliser la commande `DROP FUNCTION` pour supprimer l’UDF que vous venez de créer :

```sql theme={null}
DROP FUNCTION isBusinessHours
```

<Warning>
  **Important**

  Les UDFs dans ClickHouse Cloud **n’héritent pas des paramètres définis au niveau de l’utilisateur**. Elles s’exécutent avec les paramètres système par défaut.
</Warning>

Cela signifie :

* Les paramètres de session (définis via l’instruction `SET`) ne sont pas transmis au contexte d’exécution des UDFs
* Les paramètres du profil utilisateur ne sont pas hérités par les UDFs
* Les paramètres au niveau de la requête ne s’appliquent pas lors de l’exécution des UDFs

<div id="ui-udfs">
  ## Fonctions définies par l'utilisateur créées via l'UI
</div>

<BetaBadge />

ClickHouse Cloud offre une interface de configuration dans l'UI pour créer des fonctions définies par l'utilisateur.

Dans cet exemple, nous allons créer la même fonction définie par l'utilisateur exécutable simple, `isBusinessHours`, qui vérifie si un timestamp donné se situe dans les heures ouvrées habituelles.
Nous l'avons précédemment créée en SQL, mais cette fois, nous allons la créer en Python et la configurer via l'UI.

<Steps>
  <Step title="Créer le fichier Python" id="create-python-file">
    Créez un nouveau fichier `main.py` localement :

    ```python theme={null}
    cat > main.py << 'EOF'
    import sys
    from datetime import datetime

    for line in sys.stdin:
        ts = datetime.fromisoformat(line.strip())
        result = 1 if (0 <= ts.weekday() <= 4 and 9 <= ts.hour <= 17) else 0
        print(result)
        sys.stdout.flush()
    EOF
    ```

    Si votre script Python importe des paquets tiers, indiquez-les dans un fichier `requirements.txt`, et ClickHouse Cloud les installera pour vous. Vous pouvez aussi inclure directement les dépendances dans l’archive ZIP, mais vous devrez alors fournir les paquets mis en cache pour les deux architectures CPU ; `requirements.txt` reste donc la solution la plus simple. Par exemple :

    ```text theme={null}
    requests>=2.28.0
    numpy>=1.23.0
    ```

    <Note>
      ClickHouse Cloud s’attend à trouver `main.py` dans l’archive zip que vous téléverserez via l’UI à l’étape suivante.
      Si vous donnez un autre nom au fichier, une erreur se produira.
    </Note>
  </Step>

  <Step title="Dépendances regroupées et fichiers locaux" id="bundle-dependencies">
    Pour inclure les paquets de dépendances et tout autre fichier local (par exemple, des fichiers wheel, des fichiers de configuration ou des fichiers de données), placez-les dans le même répertoire que `main.py` et `requirements.txt`. Lorsque vous créez l’archive ZIP, incluez tous les fichiers :

    ```bash theme={null}
    zip is_business_hours.zip main.py requirements.txt
    ```

    Vous pouvez référencer, dans votre code Python, le répertoire de base du chemin local inclus en utilisant `os.path.dirname(os.path.abspath(__file__))`. Cela renvoie le chemin absolu du répertoire où se trouve votre `main.py` dans l’archive ZIP, ce qui vous permet d’accéder aux autres fichiers inclus :

    ```python theme={null}
    import os

    # Get the base directory of the bundled files
    base_dir = os.path.dirname(os.path.abspath(__file__))
    config_path = os.path.join(base_dir, 'config.json')
    ```

    Cela est utile lorsque vous devez :

    * Accéder aux fichiers de configuration inclus avec votre UDF
    * Charger des packages wheel pour des dépendances personnalisées
    * Référencer des scripts supplémentaires ou des fichiers de données

    Compressez maintenant le fichier en archive ZIP :

    ```bash theme={null}
    zip is_business_hours.zip main.py
    ```

    <Warning>
      **Les liens symboliques ne sont pas autorisés**

      ClickHouse Cloud rejette les archives UDF qui contiennent des liens symboliques. Assurez-vous que votre archive ZIP ne contient que des fichiers et répertoires ordinaires — les téléversements contenant des liens symboliques échoueront lors de la validation.
    </Warning>
  </Step>

  <Step title="Créer une UDF via l’UI" id="create-udf-via-ui">
    1. Depuis la page d’accueil de la console Cloud, cliquez sur le nom de votre organisation dans le menu en bas à gauche.
    2. Sélectionnez **Fonctions définies par l’utilisateur** dans le menu.
    3. Sur la page des fonctions définies par l’utilisateur, cliquez sur **Configurer une UDF**. Un panneau de configuration s’ouvre sur la droite de l’écran.
    4. Saisissez un nom de fonction. Pour cet exemple, utilisez `isBusinessHours`.
    5. Sélectionnez un type de fonction, **Executable pool** ou **Executable** :
       * **Executable pool** : un pool de processus persistants est maintenu, et un processus est prélevé dans ce pool pour effectuer les lectures.
       * **Executable** : le script s’exécute à chaque requête.
    6. Pour cet exemple, utilisez les paramètres par défaut. Pour obtenir la liste complète des paramètres de configuration, consultez [Executable user-defined functions](/fr/reference/functions/regular-functions/udf#executable-user-defined-functions).
    7. Cliquez sur **Parcourir le fichier** pour téléverser le fichier `.zip` créé au début de ce tutoriel.
    8. Ajoutez un nouvel argument. Pour cet exemple, ajoutez un argument `timestamp` de type `DateTime`.
    9. Sélectionnez un type de retour. Pour cet exemple, sélectionnez `Bool`.
    10. Cliquez sur **Créer une UDF**. Une boîte de dialogue affiche l’état actuel du build.
        * En cas de problème, l’état devient **error**.
        * Sinon, l’état passe de **building** à **provisioning**. Votre service doit être actif pour terminer le provisionnement. Si votre service est inactif, cliquez sur **Réveiller le service** dans le panneau **Détails de l’UDF** à côté du nom du service.
        * Une fois l’opération terminée, l’état devient **deployed**.
  </Step>

  <Step title="Testez votre UDF" id="test-your-udf">
    1. revenez à la page d’accueil de la SQL Console en cliquant sur **Settings - return to your service view** dans le coin supérieur gauche de la page
    2. cliquez sur **SQL Console** dans le menu de gauche
    3. saisissez la requête suivante :

    ```sql theme={null}
    SELECT isBusinessHours('2026-03-20 10:00:00'::DateTime), isBusinessHours('2026-03-20 23:00:00'::DateTime);
    ```

    Vous devriez obtenir le résultat suivant :

    ```response theme={null}
    true    false
    ```
  </Step>

  <Step title="Créer une nouvelle version" id="create-new-version">
    Pour modifier le code d’une UDF, créez une nouvelle version. Le panneau **Edit** sert uniquement à gérer les services auxquels une UDF est affectée ; y téléverser un fichier ne remplacera pas le code déployé.

    1. Depuis la page d’accueil de la console Cloud, cliquez sur le nom de votre organisation dans le menu en bas à gauche.
    2. Sélectionnez **User-defined functions** dans le menu.
    3. Cliquez sur les trois points sous **Actions** pour la UDF `isBusinessHours`, puis sur **Create new version**
    4. Téléversez un fichier zip contenant le code modifié, ou modifiez les paramètres, puis cliquez sur **Create new version**

    Vous avez ajouté avec succès votre première fonction définie par l’utilisateur via l’UI, confirmé qu’elle s’exécute et vu comment en créer une nouvelle version si nécessaire.
  </Step>
</Steps>

<div id="manage-udfs-with-the-cloud-api">
  ## Gérer les UDF avec l’API Cloud
</div>

<BetaBadge />

Tout ce qui est disponible dans l’UI est également accessible par programmation via l’[API ClickHouse Cloud](/fr/products/cloud/features/admin-features/api/api-overview).
Les endpoints UDF vous permettent d’automatiser l’ensemble du cycle de vie d’une UDF : téléversement d’archives sources, création de fonctions et de versions, association à des services et suppression.

<Note>
  Ces endpoints sont en bêta et le contrat de l’API est susceptible d’évoluer.
</Note>

Le workflow type pour créer et déployer une UDF via l’API est le suivant :

1. [Créez une URL de téléversement](/fr/products/cloud/api-reference/udf/udf-upload-session-create) afin d’obtenir une URL présignée pour téléverser un fichier `application/zip`, puis téléversez-y votre archive ZIP. Chaque ID de téléversement ne peut être utilisé que pour une seule tentative de création ou de création de version ; demandez une nouvelle URL de téléversement lors d’une nouvelle tentative.
2. [Créez l’UDF](/fr/products/cloud/api-reference/udf/udf-create) à partir de l’archive téléversée, en spécifiant le nom de la fonction, le runtime, les arguments et le type de retour.
3. [Associez l’UDF à un service](/fr/products/cloud/api-reference/udf/udf-attach). Si la version est omise, la dernière version prête est associée. Le service doit être en cours d’exécution ; les services inactifs peuvent d’abord être réactivés.

L’ensemble des endpoints :

| Endpoint                                                                                             | Description                                                                                   |
| ---------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------- |
| [Créer une URL de téléversement UDF](/fr/products/cloud/api-reference/udf/udf-upload-session-create) | Crée une URL présignée pour téléverser un fichier `application/zip`, limitée à l’organisation |
| [Créer une UDF](/fr/products/cloud/api-reference/udf/udf-create)                                     | Crée une nouvelle UDF à partir d’une archive téléversée                                       |
| [Lister les UDF](/fr/products/cloud/api-reference/udf/udf-list)                                      | Renvoie la dernière version de chaque UDF de l’organisation                                   |
| [Obtenir une UDF](/fr/products/cloud/api-reference/udf/udf-get)                                      | Renvoie la dernière version d’une UDF                                                         |
| [Supprimer une UDF](/fr/products/cloud/api-reference/udf/udf-delete)                                 | Supprime toutes les versions d’une UDF et la détache de tous les services                     |
| [Créer une version d’UDF](/fr/products/cloud/api-reference/udf/udf-version-create)                   | Utilise une archive source, affecte une version et lance la build de l’UDF                    |
| [Lister les versions d’UDF](/fr/products/cloud/api-reference/udf/udf-version-list)                   | Renvoie toutes les versions d’une UDF                                                         |
| [Supprimer une version d’UDF](/fr/products/cloud/api-reference/udf/udf-version-delete)               | Supprime une version d’UDF qui n’est associée à aucun service                                 |
| [Associer une UDF à un service](/fr/products/cloud/api-reference/udf/udf-attach)                     | Associe une version d’UDF à un service et remplace la version actuelle si nécessaire          |
| [Lister les associations d’UDF](/fr/products/cloud/api-reference/udf/udf-attachment-list)            | Renvoie les associations actuelles d’une UDF aux services                                     |
| [Obtenir une association d’UDF](/fr/products/cloud/api-reference/udf/udf-attachment-get)             | Renvoie l’association actuelle d’une UDF à un service                                         |
| [Détacher une UDF d’un service](/fr/products/cloud/api-reference/udf/udf-detach)                     | Détache une UDF d’un service                                                                  |

Consultez la [référence de l’API UDF](/fr/products/cloud/api-reference/udf/udf-create) pour les schémas de requête et de réponse.

<div id="manage-udfs-with-terraform">
  ## Gérer les UDF avec Terraform
</div>

Le [provider Terraform ClickHouse](https://registry.terraform.io/providers/ClickHouse/clickhouse/latest/docs) officiel inclut deux ressources pour gérer les UDF en tant qu'infrastructure as code :

* [`clickhouse_udf`](https://github.com/ClickHouse/terraform-provider-clickhouse/blob/main/docs/resources/udf.md) gère la fonction elle-même. Cette ressource accepte une archive ZIP contenant le code source de la fonction et publie une nouvelle version chaque fois que le hash de l'archive change, en attendant la fin du build.
* [`clickhouse_udf_attachment`](https://github.com/ClickHouse/terraform-provider-clickhouse/blob/main/docs/resources/udf_attachment.md) attache une version d'UDF à un service. Un service ne peut utiliser qu'une seule version d'une fonction à la fois. Vous pouvez épingler un numéro de version fixe ou référencer `clickhouse_udf.<name>.version` pour mettre automatiquement à jour les services vers la dernière version.

<Note>
  Ces ressources sont disponibles à partir de la version 3.24.0 du provider. Elles sont au statut alpha et leur comportement peut changer dans les prochaines versions du provider.
</Note>

Par exemple, pour déployer avec Terraform l'UDF `isBusinessHours` de l'exemple précédent :

```terraform theme={null}
resource "clickhouse_udf" "is_business_hours" {
  function_name = "isBusinessHours"
  runtime       = "python3.11"
  type          = "executable_pool"
  return_type   = "Bool"

  arguments = [
    { name = "timestamp", type = "DateTime" },
  ]

  source_archive_path = "${path.module}/is_business_hours.zip"
  source_archive_hash = filebase64sha256("${path.module}/is_business_hours.zip")
}

resource "clickhouse_udf_attachment" "production" {
  function_name = clickhouse_udf.is_business_hours.function_name
  service_id    = var.service_id
  version       = clickhouse_udf.is_business_hours.version
}
```

L’opération d’association ne réussit que pour les versions prêtes et peut prendre რამდენიმე minutes ; les services inactifs sont automatiquement réactivés. La suppression d’une ressource `clickhouse_udf` supprime toutes les versions de la FUNCTION et la détache de tous les services.
