GetAPI.ONE
Генерация видео с API задач ONE
Отправьте видеозадачу в формате OpenAI, сохраните её публичный идентификатор, опрашивайте точный маршрут состояния ONE до конечного состояния и получайте содержимое только после завершения.
Подтвердите протокол до расходования средств
- Выберите текущую модель каталога, которая явно поддерживает конечную точку OpenAI Video.
- Проверьте актуальные цены и поддерживаемые поля ввода модели; работа с видео может быть асинхронной и оплачиваемой.
- Для первого принятого теста используйте короткую подсказку с низким риском.
POST https://www.getapi.one/v1/videos
GET https://www.getapi.one/v1/videos/{task_id}
GET https://www.getapi.one/v1/videos/{task_id}/contentОтправка, опрос и получение
- Отправьте POST https://www.getapi.one/v1/videos и точно сохраните возвращённый идентификатор задачи.
- С фиксированным интервалом опрашивайте GET https://www.getapi.one/v1/videos/{task_id}, ограничивая число проверок; не создавайте новую задачу во время ожидания.
- Продолжайте при queued или in_progress; успешно завершайте только при completed.
- Остановитесь и покажите ошибку при failed. Считайте неизвестные состояния неуспешными и сохраняйте ответ для диагностики.
- После completed получите GET https://www.getapi.one/v1/videos/{task_id}/content.
- Передавайте содержимое блоками фиксированного размера в пределах совокупного лимита. В примере используется локальный предел 512 MiB, а частичный файл удаляется при любом сбое чтения, проверки, записи или отмены.
curl --fail-with-body https://www.getapi.one/v1/videos \
-H "Authorization: Bearer $GETAPI_ONE_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "<OPENAI_VIDEO_MODEL_ID_FROM_CURRENT_CATALOG>",
"prompt": "A five-second locked-camera product turntable on a neutral background"
}' > video-submit.jsonimport json
import os
import time
from pathlib import Path
from urllib.parse import quote
from urllib.request import Request, urlopen
base_url = "https://www.getapi.one"
api_key = os.environ["GETAPI_ONE_API_KEY"]
submitted = json.loads(Path("video-submit.json").read_text(encoding="utf-8"))
task_id = submitted.get("id") or submitted.get("task_id")
if not task_id:
raise ValueError("Submit response did not contain id or task_id")
safe_id = quote(task_id, safe="")
headers = {"Authorization": f"Bearer {api_key}"}
for attempt in range(30):
request = Request(f"{base_url}/v1/videos/{safe_id}", headers=headers)
with urlopen(request, timeout=30) as response:
task = json.load(response)
status = task.get("status")
if status == "completed":
break
if status == "failed":
raise RuntimeError(f"video task failed: {task.get('error')}")
if status not in {"queued", "in_progress"}:
raise RuntimeError(f"unknown non-success status: {status}")
if attempt == 29:
raise TimeoutError("video was not complete after 30 status checks")
time.sleep(10)
content_request = Request(
f"{base_url}/v1/videos/{safe_id}/content",
headers=headers,
)
MAX_VIDEO_BYTES = 512 * 1024 * 1024
CHUNK_BYTES = 1024 * 1024
output_path = Path("result.mp4")
created_output = False
with urlopen(content_request, timeout=60) as response:
content_type = response.headers.get_content_type()
if not content_type.startswith("video/"):
raise ValueError(f"unexpected content type: {content_type}")
try:
output = output_path.open("xb")
created_output = True
with output:
total_bytes = 0
while chunk := response.read(CHUNK_BYTES):
total_bytes += len(chunk)
if total_bytes > MAX_VIDEO_BYTES:
raise ValueError("video exceeds the local 512 MiB limit")
output.write(chunk)
except BaseException:
if created_output:
output_path.unlink(missing_ok=True)
raiseРеализуйте автомат состояний
| Состояние | Действие клиента |
|---|---|
| queued | Подождите фиксированный интервал, затем запросите тот же идентификатор задачи в пределах ограниченного числа проверок. |
| in_progress | Показывайте ход выполнения, если он предоставлен, и продолжайте опрос. |
| completed | Прекратите опрос и запросите маршрут содержимого. |
| failed | Прекратите опрос, запишите безопасные сведения об ошибке и требуйте осознанного повтора. |
Проверьте ожидаемый результат
- Ответ отправки предоставляет идентификатор задачи, а клиент сохраняет его достаточно надёжно для рабочего процесса.
- Каждый запрос состояния использует тот же идентификатор и никогда не создаёт дубликат работы.
- Загруженное содержимое имеет тип видео и открывается только после completed.
Восстановление без дублирования задач
- При тайм-ауте отправки не отправляйте задачу заново бездумно: проверьте, был ли создан идентификатор задачи или запись в консоли.
- При 404 во время опроса проверьте публичный идентификатор задачи, точный маршрут в единственном или множественном числе и тот же ключ аккаунта.
- При failed сохраните модель, безопасное краткое описание запроса, идентификатор задачи и сведения об ошибке до изменения входных данных.
Защитите медиазадачи и результаты
- Оставьте ключ и поиск задачи на аутентифицированном сервере.
- Проверяйте подсказки, загрузки, длительность, размеры и количество по контракту выбранной модели до пересылки.
- Храните одобренные результаты в контролируемом хранилище; не считайте URL содержимого постоянным или безопасным для публикации.
- Установите совокупный предел загрузки ниже бюджета памяти и хранилища, передавайте блоки фиксированного размера и удаляйте частичные артефакты при незавершённой загрузке.