> For the complete documentation index, see [llms.txt](https://docs.clore.ai/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.clore.ai/guides/guides_v2-fr/avance/cli-automation.md).

# Automatisation CLI

{% hint style="success" %}
**Prérequis :** Installez le SDK (`pip install clore-ai`) et configurez votre clé API. Voir le [Démarrage rapide Python](/guides/guides_v2-fr/prise-en-main/python-quickstart.md) si vous ne l'avez pas encore fait.
{% endhint %}

## Flux de travail de base

La boucle principale : **recherche → déployer → connecter → annuler**.

```bash
# 1. Trouver un GPU
clore search --gpu "RTX 4090" --max-price 2.0 --sort price --limit 5

# 2. Déployer (utilisez un ID de serveur de l'étape 1)
clore deploy 142 \
  --image cloreai/ubuntu22.04-cuda12 \
  --type on-demand \
  --currency bitcoin \
  --ssh-password MySecurePass \
  --port 22:tcp \
  --port 8888:http

# 3. Vérifiez vos commandes
clore orders

# 4. SSH sur le serveur
clore ssh 38

# 5. Annuler lorsque terminé
clore cancel 38

# 6. Vérifier le solde du portefeuille
clore wallets
```

***

## Référence des commandes CLI

| Commande                              | Description                                             |
| ------------------------------------- | ------------------------------------------------------- |
| `clore search`                        | Rechercher sur le marché des GPU                        |
| `clore deploy <server_id>`            | Créer une nouvelle commande                             |
| `clore orders`                        | Lister les commandes actives                            |
| `clore orders --completed`            | Lister toutes les commandes, y compris celles terminées |
| `clore ssh <order_id>`                | Se connecter en SSH à une commande active               |
| `clore cancel <order_id>`             | Annuler une commande                                    |
| `clore wallets`                       | Afficher les soldes des portefeuilles                   |
| `clore servers`                       | Lister vos serveurs hébergés                            |
| `clore server-config <name>`          | Afficher la configuration du serveur                    |
| `clore spot <server_id>`              | Voir le marché spot pour un serveur                     |
| `clore spot-price <order_id> <price>` | Définir le prix spot pour une commande                  |
| `clore config set <key> <value>`      | Définir une valeur de configuration                     |
| `clore config get <key>`              | Obtenir une valeur de configuration                     |
| `clore config show`                   | Afficher toute la configuration                         |

***

## Scripting avec la CLI

### Déployer et attendre SSH

```bash
#!/bin/bash
# deploy-and-connect.sh — Déployer un serveur et se connecter en SSH lorsqu'il est prêt

set -euo pipefail

SERVER_ID=${1:?Usage: $0 <server_id>}
IMAGE=${2:-cloreai/ubuntu22.04-cuda12}
PASSWORD="AutoDeploy$(date +%s)"

echo "🚀 Déploiement du serveur $SERVER_ID..."
clore deploy "$SERVER_ID" \
  --image "$IMAGE" \
  --type on-demand \
  --currency bitcoin \
  --ssh-password "$PASSWORD" \
  --port 22:tcp

echo "⏳ En attente que la commande soit prête..."
sleep 15

echo "📦 Commandes actives :"
clore orders

echo ""
echo "🔑 Mot de passe SSH : $PASSWORD"
echo "💡 Connectez-vous avec : clore ssh <order_id>"
```

### Trouver le GPU le moins cher et déployer

```bash
#!/bin/bash
# cheapest-gpu.sh — Trouver et déployer le GPU le moins cher correspondant aux critères

GPU_MODEL=${1:-"RTX 4090"}
MAX_PRICE=${2:-5.0}

echo "🔍 Recherche du $GPU_MODEL le moins cher à moins de \$$MAX_PRICE/h..."
clore search --gpu "$GPU_MODEL" --max-price "$MAX_PRICE" --sort price --limit 5

echo ""
read -p "Entrez l'ID du serveur à déployer (ou 'q' pour quitter) : " SERVER_ID

if [ "$SERVER_ID" = "q" ]; then
    echo "Annulé."
    exit 0
fi

read -sp "Mot de passe SSH : " SSH_PASS
echo ""

clore deploy "$SERVER_ID" \
  --image cloreai/ubuntu22.04-cuda12 \
  --type on-demand \
  --currency bitcoin \
  --ssh-password "$SSH_PASS" \
  --port 22:tcp \
  --port 8888:http

echo "✅ Déployé ! Vérifiez 'clore orders' pour le statut."
```

### Annuler toutes les commandes

```bash
#!/bin/bash
# cancel-all.sh — Annuler toutes les commandes actives

echo "📦 Commandes actuelles :"
clore orders

echo ""
read -p "Annuler TOUTES les commandes actives ? (yes/no) : " CONFIRM

if [ "$CONFIRM" = "yes" ]; then
    # Utiliser une commande Python en une ligne car la CLI annule une commande à la fois
    python3 -c "
from clore_ai import CloreAI
client = CloreAI()
orders = client.my_orders()
for o in orders:
    client.cancel_order(o.id, issue='Batch cleanup')
    print(f'Cancelled order {o.id}')
print(f'Done. Cancelled {len(orders)} orders.')
"
else
    echo "Annulé."
fi
```

***

## Intégration CI/CD

### GitHub Actions : Déployer un GPU pour l'entraînement

```yaml
# .github/workflows/train.yml
name: GPU Training

on:
  workflow_dispatch:
    inputs:
      gpu_model:
        description: 'Modèle de GPU'
        default: 'RTX 4090'
      max_price:
        description: 'Prix max USD/h'
        default: '2.0'

env:
  CLORE_API_KEY: ${{ secrets.CLORE_API_KEY }}

jobs:
  train:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - name: Install clore-ai
        run: pip install clore-ai

      - name: Find and deploy GPU
        run: |
          python3 << 'EOF'
          import time, os
          from clore_ai import CloreAI

          client = CloreAI()

          # Find cheapest matching GPU
          servers = client.marketplace(
              gpu="${{ github.event.inputs.gpu_model }}",
              max_price_usd=float("${{ github.event.inputs.max_price }}")
          )
          servers.sort(key=lambda s: s.price_usd or float("inf"))

          if not servers:
              print("No servers available!")
              exit(1)

          best = servers[0]
          print(f"Deploying on server {best.id}: {best.gpu_model} @ ${best.price_usd:.4f}/h")

          order = client.create_order(
              server_id=best.id,
              image="cloreai/ubuntu22.04-cuda12",
              type="on-demand",
              currency="bitcoin",
              ssh_password=os.environ.get("SSH_PASSWORD", "CITraining123"),
              ports={"22": "tcp"},
              command="bash /workspace/train.sh"
          )

          print(f"Order {order.id} created")

          # Wait for ready
          for _ in range(30):
              orders = client.my_orders()
              o = next((x for x in orders if x.id == order.id), None)
              if o and o.pub_cluster:
                  print(f"Ready: {o.pub_cluster}")
                  break
              time.sleep(10)

          # Save order ID for cleanup
          with open(os.environ["GITHUB_ENV"], "a") as f:
              f.write(f"ORDER_ID={order.id}\n")
          EOF

      - name: Wait for training to complete
        run: |
          echo "Training in progress..."
          # Add your monitoring logic here
          sleep 60

      - name: Cleanup GPU
        if: always()
        run: |
          python3 -c "
          from clore_ai import CloreAI
          import os
          client = CloreAI()
          order_id = int(os.environ.get('ORDER_ID', 0))
          if order_id:
              client.cancel_order(order_id, issue='CI job complete')
              print(f'Cancelled order {order_id}')
          "
```

### GitLab CI : Traitement par lots

```yaml
# .gitlab-ci.yml
gpu-batch-job:
  stage: process
  image: python:3.11
  variables:
    CLORE_API_KEY: $CLORE_API_KEY
  before_script:
    - pip install clore-ai
  script:
    - |
      python3 << 'EOF'
      from clore_ai import CloreAI
      import time

      client = CloreAI()

      servers = client.marketplace(gpu="RTX 4090", max_price_usd=3.0)
      if not servers:
          print("No GPUs available")
          exit(1)

      servers.sort(key=lambda s: s.price_usd or float("inf"))
      order = client.create_order(
          server_id=servers[0].id,
          image="cloreai/ubuntu22.04-cuda12",
          type="spot",
          currency="bitcoin",
          spot_price=0.00005,
          ports={"22": "tcp"}
      )
      print(f"Deployed: order {order.id}")

      # ... do work ...

      client.cancel_order(order.id)
      print("Done and cleaned up")
      EOF
  after_script:
    - |
      python3 -c "
      from clore_ai import CloreAI
      client = CloreAI()
      for o in client.my_orders():
          client.cancel_order(o.id, issue='CI cleanup')
      "
```

***

## Surveillance

### Vérifier périodiquement les commandes

```bash
#!/bin/bash
# monitor.sh — Vérifier les commandes toutes les 60 secondes

while true; do
    echo "=== $(date) ==="
    clore orders
    clore wallets
    echo ""
    sleep 60
done
```

### Script de surveillance Python

```python
#!/usr/bin/env python3
"""monitor-orders.py — Surveiller les commandes actives et alerter en cas de problème."""

import time
from clore_ai import CloreAI

POLL_INTERVAL = 60  # secondes
LOW_BALANCE_THRESHOLD = 0.001  # BTC

def monitor():
    client = CloreAI()

    while True:
        try:
            # Check orders
            orders = client.my_orders()
            print(f"[{time.strftime('%H:%M:%S')}] Commandes actives : {len(orders)}")
            for o in orders:
                print(f"  Commande {o.id} : type={o.type}, IP={o.pub_cluster or 'pending'}")

            # Check balance
            wallets = client.wallets()
            for w in wallets:
                if w.name.lower() == "bitcoin" and w.balance < LOW_BALANCE_THRESHOLD:
                    print(f"  ⚠️  Solde BTC faible : {w.balance:.8f}")

        except Exception as e:
            print(f"  ❌ Erreur : {e}")

        time.sleep(POLL_INTERVAL)

if __name__ == "__main__":
    monitor()
```

***

## Opérations par lot

### Déployer sur plusieurs serveurs

```bash
#!/bin/bash
# batch-deploy.sh — Déployer sur plusieurs serveurs

SERVER_IDS=(142 305 891 450)
IMAGE="cloreai/ubuntu22.04-cuda12"
PASSWORD="BatchRun$(date +%s)"

for SID in "${SERVER_IDS[@]}"; do
    echo "🚀 Déploiement sur le serveur $SID..."
    clore deploy "$SID" \
      --image "$IMAGE" \
      --type on-demand \
      --currency bitcoin \
      --ssh-password "$PASSWORD" \
      --port 22:tcp \
      || echo "⚠️  Échec du déploiement sur $SID"
    sleep 6  # Respecter les limites de taux
done

echo ""
echo "📦 Toutes les commandes :"
clore orders
echo "🔑 Mot de passe : $PASSWORD"
```

### Déploiement par lot avec Python (Async)

```python
#!/usr/bin/env python3
"""batch-deploy.py — Déployer sur plusieurs serveurs simultanément."""

import asyncio
from clore_ai import AsyncCloreAI
from clore_ai.exceptions import CloreAPIError

async def batch_deploy(server_ids, image="cloreai/ubuntu22.04-cuda12"):
    async with AsyncCloreAI() as client:
        tasks = [
            client.create_order(
                server_id=sid,
                image=image,
                type="on-demand",
                currency="bitcoin",
                ssh_password="BatchPass123",
                ports={"22": "tcp"}
            )
            for sid in server_ids
        ]

        results = await asyncio.gather(*tasks, return_exceptions=True)

        for sid, result in zip(server_ids, results):
            if isinstance(result, CloreAPIError):
                print(f"❌ Serveur {sid} : {result}")
            elif isinstance(result, Exception):
                print(f"❌ Serveur {sid} : {result}")
            else:
                print(f"✅ Serveur {sid} : Commande {result.id}")

if __name__ == "__main__":
    import sys
    server_ids = [int(x) for x in sys.argv[1:]]
    if not server_ids:
        print("Usage: python batch-deploy.py 142 305 891")
        exit(1)
    asyncio.run(batch_deploy(server_ids))
```

Utilisation :

```bash
python batch-deploy.py 142 305 891
```

### Scanner le marché Spot

```bash
#!/bin/bash
# spot-scanner.sh — Scanner les prix spot pour une liste de serveurs

SERVERS=(6 12 42 100)

echo "📊 Scan du marché Spot — $(date)"
echo "---"

for SID in "${SERVERS[@]}"; do
    echo "Serveur $SID :"
    clore spot "$SID"
    echo ""
done
```

***

## Jobs Cron

### Vérification quotidienne du prix GPU

```bash
# Ajouter au crontab : crontab -e
# Exécuter tous les jours à 9h
0 9 * * * CLORE_API_KEY=your_key /usr/local/bin/clore search --gpu "RTX 4090" --sort price --limit 5 >> /var/log/clore-prices.log 2>&1
```

### Vérification horaire du solde

```bash
# Vérifier le solde toutes les heures
0 * * * * CLORE_API_KEY=your_key /usr/local/bin/clore wallets >> /var/log/clore-balance.log 2>&1
```

***

## Conseils

1. **Toujours définir `CLORE_API_KEY`** comme variable d'environnement dans les scripts et CI
2. **Ajouter `sleep 6`** entre les commandes de déploiement dans les boucles bash pour respecter les limites de taux
3. **Utiliser `--type spot`** pour les jobs par lot/CI — moins cher et interrompable, c'est acceptable
4. **Annuler les commandes dans `after_script`** / `if: always()` pour éviter une facturation oubliée
5. **Stocker les mots de passe SSH dans les secrets** (GitHub Secrets, variables GitLab CI, etc.)
6. **Utiliser `clore orders --completed`** pour auditer l'utilisation passée

***

## Étapes suivantes

* [Guide du SDK Python](/guides/guides_v2-fr/avance/python-sdk.md) — Référence complète du SDK avec modèles async
* [Traitement par lots](/guides/guides_v2-fr/avance/batch-processing.md) — Traiter de grandes charges de travail IA
* [Intégration API](/guides/guides_v2-fr/avance/api-integration.md) — Connecter les services IA à vos applications


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.clore.ai/guides/guides_v2-fr/avance/cli-automation.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
