> 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-ru/prodvinutye/cli-automation.md).

# Автоматизация через CLI

{% hint style="success" %}
**Требования:** Установите SDK (`pip install clore-ai`) и настройте ваш API-ключ. Смотрите [Python Quickstart](/guides/guides_v2-ru/nachalo-raboty/python-quickstart.md) если вы ещё не сделали этого.
{% endhint %}

## Базовый рабочий процесс

Основной цикл: **поиск → развёртывание → подключение → отмена**.

```bash
# 1. Найдите GPU
clore search --gpu "RTX 4090" --max-price 2.0 --sort price --limit 5

# 2. Развернуть (используйте ID сервера из шага 1)
clore deploy 142 \
  --image cloreai/ubuntu22.04-cuda12 \
  --type on-demand \
  --currency bitcoin \
  --ssh-password MySecurePass \
  --port 22:tcp \
  --port 8888:http

# 3. Проверьте ваши заказы
clore orders

# 4. Подключитесь по SSH к серверу
clore ssh 38

# 5. Отмените по завершении
clore cancel 38

# 6. Проверьте баланс кошелька
clore wallets
```

***

## Справочник команд CLI

| Команда                               | Описание                                           |
| ------------------------------------- | -------------------------------------------------- |
| `clore search`                        | Поиск на рынке GPU                                 |
| `clore deploy <server_id>`            | Создать новый заказ                                |
| `clore orders`                        | Показать активные заказы                           |
| `clore orders --completed`            | Показать все заказы включая завершённые            |
| `clore ssh <order_id>`                | Подключиться по SSH к активному заказу             |
| `clore cancel <order_id>`             | Отменить заказ                                     |
| `clore wallets`                       | Показать балансы кошельков                         |
| `clore servers`                       | Список ваших размещённых серверов                  |
| `clore server-config <name>`          | Показать конфигурацию сервера                      |
| `clore spot <server_id>`              | Просмотреть рынок спотовых предложений для сервера |
| `clore spot-price <order_id> <price>` | Установить спотовую цену для заказа                |
| `clore config set <key> <value>`      | Установить значение конфигурации                   |
| `clore config get <key>`              | Получить значение конфигурации                     |
| `clore config show`                   | Показать всю конфигурацию                          |

***

## Скрипты с использованием CLI

### Развернуть и дождаться SSH

```bash
#!/bin/bash
# deploy-and-connect.sh — Развернуть сервер и подключиться по SSH, когда он готов

set -euo pipefail

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

echo "🚀 Разворачиваем сервер $SERVER_ID..."
clore deploy "$SERVER_ID" \
  --image "$IMAGE" \
  --type on-demand \
  --currency bitcoin \
  --ssh-password "$PASSWORD" \
  --port 22:tcp

echo "⏳ Ожидание готовности заказа..."
sleep 15

echo "📦 Активные заказы:"
clore orders

echo ""
echo "🔑 SSH пароль: $PASSWORD"
echo "💡 Подключение: clore ssh <order_id>"
```

### Найти самый дешёвый GPU и развернуть

```bash
#!/bin/bash
# cheapest-gpu.sh — Найти и развернуть самый дешёвый GPU, соответствующий критериям

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

echo "🔍 Поиск самого дешёвого $GPU_MODEL ниже \$$MAX_PRICE/ч..."
clore search --gpu "$GPU_MODEL" --max-price "$MAX_PRICE" --sort price --limit 5

echo ""
read -p "Введите ID сервера для развертывания (или 'q' для выхода): " SERVER_ID

if [ "$SERVER_ID" = "q" ]; then
    echo "Отменено."
    exit 0
fi

read -sp "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 "✅ Развернуто! Проверьте 'clore orders' для статуса."
```

### Отмена всех заказов

```bash
#!/bin/bash
# cancel-all.sh — Отменить все активные заказы

echo "📦 Текущие заказы:"
clore orders

echo ""
read -p "Отменить ВСЕ активные заказы? (yes/no): " CONFIRM

if [ "$CONFIRM" = "yes" ]; then
    # Используем однострочный Python, так как CLI отменяет по одному
    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 "Отменено."
fi
```

***

## Интеграция CI/CD

### GitHub Actions: Развернуть GPU для обучения

```yaml
# .github/workflows/train.yml
name: Обучение на GPU

on:
  workflow_dispatch:
    inputs:
      gpu_model:
        description: 'Модель GPU'
        default: 'RTX 4090'
      max_price:
        description: 'Макс. цена USD/ч'
        default: '2.0'

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

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

      - name: Установить clore-ai
        run: pip install clore-ai

      - name: Найти и развернуть GPU
        run: |
          python3 << 'EOF'
          import time, os
          from clore_ai import CloreAI

          client = CloreAI()

          # Найти самый дешёвый подходящий 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("Нет доступных серверов!")
              exit(1)

          best = servers[0]
          print(f"Разворачиваем на сервере {best.id}: {best.gpu_model} @ ${best.price_usd:.4f}/ч")

          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.id} создан")

          # Ожидание готовности
          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"Готово: {o.pub_cluster}")
                  break
              time.sleep(10)

          # Сохранить ID заказа для очистки
          with open(os.environ["GITHUB_ENV"], "a") as f:
              f.write(f"ORDER_ID={order.id}\n")
          EOF

      - name: Ожидание завершения обучения
        run: |
          echo "Обучение в процессе..."
          # Добавьте здесь логику мониторинга
          sleep 60

      - name: Очистка 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: Пакетная обработка

```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("Нет доступных GPU")
          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"Развернуто: заказ {order.id}")

      # ... выполняем работу ...

      client.cancel_order(order.id)
      print("Готово и очищено")
      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')
      "
```

***

## Мониторинг

### Периодическая проверка заказов

```bash
#!/bin/bash
# monitor.sh — Проверять заказы каждые 60 секунд

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

### Python-скрипт для мониторинга

```python
#!/usr/bin/env python3
"""monitor-orders.py — Мониторить активные заказы и оповещать о проблемах."""

import time
from clore_ai import CloreAI

POLL_INTERVAL = 60  # секунд
LOW_BALANCE_THRESHOLD = 0.001  # BTC

def monitor():
    client = CloreAI()

    while True:
        try:
            # Проверить заказы
            orders = client.my_orders()
            print(f"[{time.strftime('%H:%M:%S')}] Активные заказы: {len(orders)}")
            for o in orders:
                print(f"  Заказ {o.id}: type={o.type}, IP={o.pub_cluster or 'pending'}")

            # Проверить баланс
            wallets = client.wallets()
            for w in wallets:
                if w.name.lower() == "bitcoin" and w.balance < LOW_BALANCE_THRESHOLD:
                    print(f"  ⚠️  Низкий баланс BTC: {w.balance:.8f}")

        except Exception as e:
            print(f"  ❌ Ошибка: {e}")

        time.sleep(POLL_INTERVAL)

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

***

## Пакетные операции

### Развертывание на нескольких серверах

```bash
#!/bin/bash
# batch-deploy.sh — Развернуть на нескольких серверах

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

for SID in "${SERVER_IDS[@]}"; do
    echo "🚀 Разворачиваем на сервере $SID..."
    clore deploy "$SID" \
      --image "$IMAGE" \
      --type on-demand \
      --currency bitcoin \
      --ssh-password "$PASSWORD" \
      --port 22:tcp \
      || echo "⚠️  Не удалось развернуть на $SID"
    sleep 6  # Учитывать ограничения частоты запросов
done

echo ""
echo "📦 Все заказы:"
clore orders
echo "🔑 Пароль: $PASSWORD"
```

### Пакетное развертывание с Python (Async)

```python
#!/usr/bin/env python3
"""batch-deploy.py — Развернуть на нескольких серверах одновременно."""

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"❌ Сервер {sid}: {result}")
            elif isinstance(result, Exception):
                print(f"❌ Сервер {sid}: {result}")
            else:
                print(f"✅ Сервер {sid}: Заказ {result.id}")

if __name__ == "__main__":
    import sys
    server_ids = [int(x) for x in sys.argv[1:]]
    if not server_ids:
        print("Использование: python batch-deploy.py 142 305 891")
        exit(1)
    asyncio.run(batch_deploy(server_ids))
```

Использование:

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

### Сканер спотового рынка

```bash
#!/bin/bash
# spot-scanner.sh — Сканиpовать спотовые цены для списка серверов

SERVERS=(6 12 42 100)

echo "📊 Скан спотового рынка — $(date)"
echo "---"

for SID in "${SERVERS[@]}"; do
    echo "Сервер $SID:"
    clore spot "$SID"
    echo ""
done
```

***

## Cron-задачи

### Ежедневная проверка цены GPU

```bash
# Добавить в crontab: crontab -e
# Запуск каждый день в 9:00
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
```

### Почасовая проверка баланса

```bash
# Проверять баланс каждый час
0 * * * * CLORE_API_KEY=your_key /usr/local/bin/clore wallets >> /var/log/clore-balance.log 2>&1
```

***

## Советы

1. **Всегда задавайте `CLORE_API_KEY`** как переменную окружения в скриптах и CI
2. **Добавьте `sleep 6`** между командами deploy в bash-циклах, чтобы учитывать ограничения частоты запросов
3. **Используйте `--type spot`** для пакетных/CI задач — дешевле, и прерываемость допустима
4. **Отменяйте заказы в `after_script`** / `if: always()` чтобы избежать забытых платежей
5. **Храните SSH-пароли в секрете** (GitHub Secrets, переменные GitLab CI и т.д.)
6. **Используйте `clore orders --completed`** чтобы иметь аудит прошлых действий

***

## Дальнейшие шаги

* [Руководство по Python SDK](/guides/guides_v2-ru/prodvinutye/python-sdk.md) — Полная справка по SDK с примерами async
* [Пакетная обработка](/guides/guides_v2-ru/prodvinutye/batch-processing.md) — Обработка больших AI-нагрузок
* [Интеграция API](/guides/guides_v2-ru/prodvinutye/api-integration.md) — Подключение AI-сервисов к вашим приложениям


---

# 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, and the optional `goal` query parameter:

```
GET https://docs.clore.ai/guides/guides_v2-ru/prodvinutye/cli-automation.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

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.
