15 KiB
DaSiWa API Guide
Полное руководство по использованию DaSiWa I2V/FLF2V API для генерации видео через ComfyUI.
📋 Содержание
Обзор
DaSiWa API — асинхронный REST API для генерации видео из изображений с использованием DaSiWa WAN 2.2 TastySin v8.1 моделей через ComfyUI.
Архитектура: Submit → Poll → Retrieve (как RunPod)
Base URL: http://<server_ip>:8080
Аутентификация: HMAC-SHA256 с timestamp и nonce
Аутентификация
Все endpoints (кроме /health) требуют HMAC подписи.
Заголовки запроса
X-Client-Id: <ваш_client_id>
X-Timestamp: <unix_timestamp>
X-Nonce: <случайная_строка_32_символа>
X-Signature: <hmac_sha256_подпись>
Алгоритм подписи
import hmac
import hashlib
import time
import secrets
timestamp = str(int(time.time()))
nonce = secrets.token_hex(16)
body = json.dumps(payload).encode('utf-8')
message = f"{timestamp}.{nonce}.".encode() + body
signature = hmac.new(
secret_key.encode(),
message,
hashlib.sha256
).hexdigest()
Защита от replay-атак
- Timestamp: запросы старше 5 минут отклоняются
- Nonce: каждый nonce можно использовать только один раз
- Signature: уникальна для каждого запроса
Endpoints
GET /health
Health check сервера. Не требует аутентификации.
Response:
{
"status": "ok",
"comfyui": "ok",
"queue": 0,
"timestamp": 1234567890
}
Поля:
status— статус API сервера (ok/error)comfyui— статус ComfyUI (ok/unavailable)queue— количество задач в очередиtimestamp— текущее время сервера (unix)
GET /comfyui/status
Детальная проверка статуса ComfyUI. Не требует аутентификации.
Response (ComfyUI доступен):
{
"comfyui": "ok",
"ready": true,
"error": null,
"timestamp": 1234567890
}
Response (ComfyUI недоступен):
{
"comfyui": "unavailable",
"ready": false,
"error": "Connection failed: Connection refused",
"timestamp": 1234567890
}
Поля:
comfyui— статус (ok/unavailable)ready— готов ли ComfyUI принимать задачи (true/false)error— описание ошибки (если есть)timestamp— текущее время сервера (unix)
Использование: Проверяй этот endpoint перед отправкой задач, чтобы убедиться что ComfyUI запущен.
POST /run
Поставить задачу на генерацию видео в очередь.
Request Body:
{
"image_base64": "base64_encoded_image_data",
"prompt": "woman dancing gracefully",
"negative_prompt": "blurry, low quality",
"last_image_base64": "base64_encoded_last_frame",
"width": 528,
"height": 768,
"length": 81,
"steps": 4,
"cfg": 1.0,
"seed": -1,
"fps": 16,
"sampler_name": "euler",
"scheduler": "linear_quadratic"
}
Обязательные поля:
image_base64— первый кадр (base64)prompt— текстовое описание
Опциональные поля:
last_image_base64— последний кадр для FLF2V режимаnegative_prompt— негативный промпт (default: встроенный)width— ширина (default: 528, кратно 16)height— высота (default: 768, кратно 16)length— количество кадров (default: 81)steps— шаги сэмплинга (default: 4)cfg— CFG scale (default: 1.0)seed— сид (-1 = random, default: -1)fps— кадров в секунду (default: 16)sampler_name— сэмплер (default: "euler")scheduler— планировщик (default: "linear_quadratic")
Response:
{
"id": "550e8400-e29b-41d4-a716-446655440000",
"status": "IN_QUEUE"
}
Коды ответа:
200— задача принята400— ошибка валидации (нет изображения)401— ошибка аутентификации
GET /status/<job_id>
Получить статус задачи.
Response (IN_QUEUE):
{
"id": "550e8400-e29b-41d4-a716-446655440000",
"status": "IN_QUEUE"
}
Response (IN_PROGRESS):
{
"id": "550e8400-e29b-41d4-a716-446655440000",
"status": "IN_PROGRESS"
}
Response (COMPLETED):
{
"id": "550e8400-e29b-41d4-a716-446655440000",
"status": "COMPLETED",
"output": {
"video": "base64_encoded_video_data",
"seed": 42,
"mode": "I2V",
"elapsed": 45.2
}
}
Response (FAILED):
{
"id": "550e8400-e29b-41d4-a716-446655440000",
"status": "FAILED",
"error": "Video generation failed — no output from ComfyUI"
}
Коды ответа:
200— статус получен404— задача не найдена401— ошибка аутентификации
POST /purge/<job_id>
Удалить завершённую задачу из памяти сервера (освободить RAM от base64 видео).
Response:
{
"id": "550e8400-e29b-41d4-a716-446655440000",
"purged": true
}
Коды ответа:
200— задача удалена400— нельзя удалить активную задачу (IN_QUEUE / IN_PROGRESS)404— задача не найдена401— ошибка аутентификации
Параметры генерации
Режимы работы
I2V (Image to Video):
- Генерация видео из одного изображения
- Передаётся только
image_base64
FLF2V (First-Last Frame to Video):
- Генерация видео между двумя кадрами
- Передаются
image_base64+last_image_base64
Рекомендуемые значения
| Параметр | I2V | FLF2V | Описание |
|---|---|---|---|
width |
528 | 528 | Ширина (кратно 16) |
height |
768 | 768 | Высота (кратно 16) |
length |
81 | 81 | Кол-во кадров (~5 сек при 16fps) |
steps |
4 | 4 | DaSiWa оптимизирован под 4 шага |
cfg |
1.0 | 1.0 | CFG scale (DaSiWa работает с 1.0) |
fps |
16 | 16 | Кадров в секунду |
sampler_name |
euler | euler | Сэмплер |
scheduler |
linear_quadratic | linear_quadratic | Планировщик |
Ограничения
- Размеры: должны быть кратны 16
- Length: рекомендуется кратно 8 + 1 (например: 81, 89, 97)
- Steps: DaSiWa TastySin оптимизирован под 4 шага (можно больше, но медленнее)
- CFG: значения > 2.0 могут давать артефакты
Примеры использования
Python (с библиотекой requests)
import requests
import base64
import json
import time
from hmac_auth import sign_request
# Загрузка ключей
with open('keys.json') as f:
keys = json.load(f)
# Подготовка изображения
with open('photo.png', 'rb') as f:
image_b64 = base64.b64encode(f.read()).decode()
# Payload
payload = {
"image_base64": image_b64,
"prompt": "woman dancing gracefully",
"width": 528,
"height": 768,
"length": 81,
"steps": 4,
"cfg": 1.0,
"seed": -1,
"fps": 16
}
# 1. Submit job
body = json.dumps(payload).encode('utf-8')
auth_headers = sign_request(body, keys['secret_key'], keys['client_id'])
headers = {'Content-Type': 'application/json', **auth_headers}
response = requests.post(
'http://server:8080/run',
data=body,
headers=headers
)
job_id = response.json()['id']
print(f"Job ID: {job_id}")
# 2. Poll status
while True:
auth_headers = sign_request(b"", keys['secret_key'], keys['client_id'])
response = requests.get(
f'http://server:8080/status/{job_id}',
headers=auth_headers
)
data = response.json()
if data['status'] == 'COMPLETED':
video_b64 = data['output']['video']
video_bytes = base64.b64decode(video_b64)
with open('output.mp4', 'wb') as f:
f.write(video_bytes)
print(f"Video saved! Seed: {data['output']['seed']}")
break
elif data['status'] == 'FAILED':
print(f"Error: {data['error']}")
break
else:
print(f"Status: {data['status']}")
time.sleep(5)
# 3. Purge job
auth_headers = sign_request(b"{}", keys['secret_key'], keys['client_id'])
requests.post(
f'http://server:8080/purge/{job_id}',
json={},
headers={'Content-Type': 'application/json', **auth_headers}
)
cURL
# 1. Submit job
curl -X POST http://server:8080/run \
-H "Content-Type: application/json" \
-H "X-Client-Id: your_client_id" \
-H "X-Timestamp: $(date +%s)" \
-H "X-Nonce: $(openssl rand -hex 16)" \
-H "X-Signature: <calculated_signature>" \
-d '{
"image_base64": "...",
"prompt": "woman dancing"
}'
# Response: {"id": "abc-123", "status": "IN_QUEUE"}
# 2. Check status
curl http://server:8080/status/abc-123 \
-H "X-Client-Id: your_client_id" \
-H "X-Timestamp: $(date +%s)" \
-H "X-Nonce: $(openssl rand -hex 16)" \
-H "X-Signature: <calculated_signature>"
# 3. Purge
curl -X POST http://server:8080/purge/abc-123 \
-H "Content-Type: application/json" \
-H "X-Client-Id: your_client_id" \
-H "X-Timestamp: $(date +%s)" \
-H "X-Nonce: $(openssl rand -hex 16)" \
-H "X-Signature: <calculated_signature>" \
-d '{}'
Коды ошибок
| Код | Описание | Решение |
|---|---|---|
400 |
Нет входного изображения | Передайте image_base64 |
401 |
Invalid client ID | Проверьте client_id в keys.json |
401 |
Invalid timestamp | Синхронизируйте время на клиенте и сервере |
401 |
Nonce already used | Replay-атака или дублирующий запрос |
401 |
Invalid signature | Проверьте secret_key и алгоритм подписи |
404 |
Job not found | Job ID не существует или уже удалён |
500 |
Internal server error | Проверьте логи сервера (journalctl -u dasiwa-api) |
Best Practices
1. Polling интервал
- Рекомендуется: 5-10 секунд
- Не рекомендуется: < 2 секунд (нагрузка на сервер)
- Генерация обычно занимает 30-60 секунд
2. Timeout
- Установите timeout на polling: 30 минут (1800 секунд)
- Если задача не завершилась за это время — проверьте логи сервера
3. Purge после использования
- Всегда вызывайте
/purge/<id>после получения видео - Base64 видео занимает ~10-50 MB RAM на сервере
- Без purge память будет расти
4. Обработка ошибок
try:
result = wait_for_completion(server, job_id, ...)
except RuntimeError as e:
if "Timeout" in str(e):
# Задача зависла — проверьте сервер
pass
elif "Job failed" in str(e):
# Ошибка генерации — проверьте параметры
pass
5. Retry логика
- При
401ошибках — не retry (проблема с ключами) - При
500ошибках — retry с exponential backoff - При
404на/status— задача потеряна, не retry
6. Размер изображений
- Оптимально: 528x768 или 768x528
- Большие размеры → больше VRAM → медленнее
- Маленькие размеры → хуже качество
7. Seed для воспроизводимости
- Если нужен тот же результат — используйте тот же seed
- Seed из ответа
output.seed— сохраните для повтора
8. Мониторинг очереди
response = requests.get('http://server:8080/health')
queue_size = response.json()['queue']
if queue_size > 5:
print("Очередь большая, ожидайте дольше")
Лимиты и производительность
Текущие лимиты
- Одновременные задачи: 1 (1 GPU = 1 задача)
- Размер очереди: не ограничен (но рекомендуется < 10)
- Размер изображения: max 2048x2048 (теоретически)
- Длина видео: max ~300 кадров (ограничено VRAM)
Производительность
| Параметры | Время генерации | VRAM |
|---|---|---|
| 528x768, 81 frames, 4 steps | ~30-45s | ~18 GB |
| 768x528, 81 frames, 4 steps | ~30-45s | ~18 GB |
| 528x768, 161 frames, 4 steps | ~60-90s | ~24 GB |
Время указано для RTX 4090 / A100
Troubleshooting
Задача зависла в IN_PROGRESS
- Проверьте логи сервера:
journalctl -u dasiwa-api -f - Проверьте ComfyUI:
curl http://localhost:8188 - Перезапустите сервис:
systemctl restart dasiwa-api
Ошибка "Video generation failed"
- ComfyUI не запущен или недоступен
- Недостаточно VRAM
- Workflow файл повреждён
Медленная генерация
- Проверьте загрузку GPU:
nvidia-smi - Убедитесь что модели загружены в VRAM (первый запрос медленнее)
- Уменьшите
lengthили размеры
Changelog
v2.0 (2026-03-07)
- ✨ Асинхронный API (submit + poll)
- ✨ Endpoints:
/run,/status,/purge - ✨ Background worker thread
- ✨ Queue management
- 🔧 Обновлён на DaSiWa WAN 2.2 TastySin v8.1
- 🔧 Упрощён workflow (14 нод вместо 50+)
v1.0 (2026-03-06)
- 🎉 Первый релиз
- ✅ Синхронный
/generateendpoint - ✅ HMAC аутентификация
- ✅ I2V и FLF2V режимы