튜토리얼
HiAPI API로 kling-3.0-omni/image-to-video 사용하는 방법: curl 및 Python 가이드
image-to-video 엔드포인트가 하는 일
비디오 생성은 단일 동기 호출이 아닙니다. HiAPI에서 kling-3.0-omni/image-to-video는 제출 후 폴링 패턴을 따릅니다: 작업을 설명하는 HTTP 요청을 보내면 API가 요청을 수락하고 작업 식별자를 반환하며, 그런 다음 비디오 생성이 완료될 때까지 해당 작업을 조회합니다.
이러한 2단계 구조에는 충분한 이유가 있습니다. 정적 이미지에서 비디오를 렌더링하려면 시간이 걸립니다——일반적인 HTTP 요청이 열린 상태로 유지되어야 하는 시간을 훨씬 초과합니다. 엔드포인트가 파일이 준비될 때까지 차단된다면, 매 호출마다 게이트웨이 타임아웃과 연결 끊김을 겪게 될 것입니다. 작업 핸들을 즉시 반환함으로써 API는 얼마나 기다릴지, 얼마나 자주 확인할지, 오류 발생 시 어떻게 처리할지를 코드가 스스로 결정하게 합니다.
일반적인 작업은 세 가지 논리적 부분으로 구성됩니다:
- 입력 미디어——샷에 앵커를 제공하는 이미지(또는 이미지 세트).
- 생성 설정——프롬프트 텍스트, 모션 관련 옵션, 오디오 및 해상도 선택.
- 수명 주기——작업 ID가 포함된 제출 응답, 이어서 최종 비디오 URL 또는 실패 이유를 반환하는 상태 확인.
이 엔드포인트를 영수증이 있는 대기열이라고 생각하면 도움이 됩니다. 제출 호출은 작업 티켓을 제출하는 것이고, 영수증은 작업 ID이며, 폴링 호출은 카운터에 주문이 준비되었는지 묻는 것입니다. 제출 시 비디오 자체는 반환되지 않으므로, 작성하는 모든 클라이언트는 처음부터 이 두 단계를 중심으로 구성되어야 합니다.
여기서 두 가지 결과가 따릅니다. 첫째, 오류 처리는 분리되어야 합니다: 거부된 요청 본문은 제출 시 문제로 코드에서 수정할 수 있지만, 렌더링 실패는 작업 수준 문제로 동일한 요청 본문을 아무리 재시도해도 해결되지 않습니다. 둘째, 작업 ID를 저장할 곳이 필요합니다——로그 줄, 데이터베이스 행, 스크립트의 변수——왜냐하면 그것이 진행 중인 작업을 붙잡을 수 있는 유일한 핸들이기 때문입니다.
이 멘탈 모델을 확립하면, 이 가이드의 나머지 부분은 주로 파이프라인 작업입니다: 요청을 구성한 다음 올바르게 기다리는 것입니다.
작동하는 curl 요청 구성하기
가능한 한 최소한의 작동하는 요청부터 시작하여 수락되는지 확인한 다음 옵션을 추가하세요. 정확한 JSON 필드 이름과 엔드포인트 경로는 HiAPI의 해당 모델 참조 페이지에 정의되어 있습니다——블로그 글(이 글 포함)의 스니펫을 믿지 말고 해당 페이지에서 현재 스키마를 확인하세요.
제출 호출은 예측 가능한 구조를 가집니다. Authorization 헤더에 HiAPI API 키로 인증하고, Content-Type: application/json을 선언하며, JSON 요청 본문을 보냅니다. 개념적으로 요청 본문은 다음과 같습니다:
{
"model": "kling-3.0-omni/image-to-video",
"input": {
"image": "https://your-cdn.example.com/frame-first.jpg",
"prompt": "A slow dolly-in as morning light crosses the room"
}
}
구조가 리터럴 값보다 중요합니다: 모델 식별자, 소스 이미지 참조와 프롬프트를 담는 입력 객체, 그리고 생성 옵션을 위한 공간. 모든 키를 하드코딩하기 전에 현재 문서와 대조하여 검증하세요.
동등한 curl 호출은 일반적인 패턴을 따릅니다:
curl -sS -X POST "$HIAPI_BASE_URL/v1/video/generations" \
-H "Authorization: Bearer $HIAPI_API_KEY" \
-H "Content-Type: application/json" \
-d @request.json
요청 본문을 인라인 대신 request.json에 저장하면 반복 작업이 훨씬 쉬워집니다——셸 히스토리 항목이 아닌 파일을 편집하게 됩니다.
응답 읽기
성공적인 제출은 의도적으로 평범합니다. 작업 식별자와 수락되었지만 완료되지 않았음을 나타내는 상태를 기대하세요. 파싱하고, 출력하고, 저장하세요:
curl -sS -X POST "$HIAPI_BASE_URL/v1/video/generations" \
-H "Authorization: Bearer $HIAPI_API_KEY" \
-H "Content-Type: application/json" \
-d @request.json | tee submit.json
먼저 HTTP 상태 코드를 확인하세요.4xx는 요청 자체가 거부되었음을 의미합니다——잘못된 키, 형식이 잘못된 JSON, 지원되지 않는 옵션, 유효하지 않은 이미지 URL.2xx는 작업이 시스템에 들어갔음을 의미하며, 그 순간부터 유용한 신호는 HTTP 상태 코드가 아닌 작업 상태에서 옵니다.
폴링 코드를 작성하기 전에 먼저 수동으로 한 번 제출을 실행하세요. 출력에서 작업 ID를 볼 수 있는지 확인하세요. 이 수동 왕복은 대부분의 구성 오류를 조기에 발견합니다.
첫 프레임 및 마지막 프레임 입력 처리하기
보내는 이미지는 단순한 참조가 아닙니다——샷의 시작점을 제약합니다. 이 차이가 이 섹션의 대부분의 설계 결정을 이끕니다.
첫 프레임만
단일 이미지를 제공할 때, 그것을 오프닝 프레임으로 취급하세요. 그런 다음 프롬프트는 해당 프레임에서 시작하여 어떤 일이 일어나야 하는지를 설명합니다: 카메라 움직임, 피사체 동작, 조명 변화, 리듬. 모델이 첫 프레임 이후의 모든 것을 창조해야 하므로, 궤적을 설명하는 프롬프트가 정적 장면을 설명하는 프롬프트보다 효과적입니다. "정지 상태로 유지하며 아름답게 보인다"는 모델에게 애니메이션할 내용을 전혀 주지 않습니다; "그녀가 창문 쪽으로 돌아서고 빛이 따뜻해진다"는 방향을 제공합니다.
마지막 프레임 추가
마지막 프레임 입력은 작업을 보간 문제로 바꿉니다. 두 끝점을 제공하면 모델이 그 사이의 경로를 생성합니다. 이것은 제어된 전환에 매우 강력합니다——제품이 정면도에서 후면도로 회전하거나, 캐릭터가 두 포즈 사이를 전환하는 경우——왜냐하면 끝점이 상상되는 것이 아니라 고정되기 때문입니다.
세 가지 실용적 참고 사항:
- 두 프레임을 호환 가능하게 유지하세요. 유사한 프레이밍, 원근, 피사체 비율이 보간을 신뢰할 수 있게 만듭니다. 크게 다른 구도는 모델이 존재하지 않을 수도 있는 다리를 발명하도록 강제합니다.
- 프롬프트를 다시 작성하세요. 두 프레임이 있을 때, 텍스트는 끝점이 아닌 그들 사이의 움직임을 설명해야 합니다. 모션 스타일과 지속 시간을 명명하는 것이 이미 제공한 최종 상태를 서술하는 것보다 더 자연스럽습니다.
- 요청 구조가 바뀌리라고 예상하세요. 마지막 프레임은 별도의 입력 필드이므로 요청 본문에 키가 하나 더 생깁니다. 요청 객체를 구성할 때 모든 것을 재구성하지 않고도 선택적 필드를 추가할 수 있도록 만드세요.
코드에서 프레임을 느슨한 URL 집합이 아닌 작은 명명된 입력으로 취급하세요:
inputs = {"image": first_frame_url}
if last_frame_url:
inputs["last_frame"] = last_frame_url
이 조건문은 단일 프레임과 두 프레임 호출을 동일한 코드 경로에 유지하며, 변형 생성을 시작하면 이것이 중요해집니다.
마지막으로, 프레임을 안정적으로 접근 가능한 곳에 호스팅하세요. 작업 중간에 만료되는 URL은 제출 후 실패하며, 오류는 리소스 문제가 아닌 생성 실패처럼 보입니다.
오디오 및 출력 해상도 구성하기
오디오와 해상도는 요청 수준 선택이며 전역 설정이 아닙니다. 작업별로 결정하므로, 한 번 설정하고 잊어버리는 구성 상수가 아닌 프롬프트 옆의 요청 본문 빌더에 있어야 합니다.
오디오
오디오 옵션은 일반적으로 비디오와 함께 사운드를 요청하거나 생략할 수 있게 합니다. 사용 사례에 따른 모델링 결정으로 취급하세요: 소셜 클립은 생성된 오디오의 이점을 얻을 수 있지만, 편집기에서 사운드를 입힐 클립은 오디오를 포함하지 않아야 할 수 있습니다. 절대 사용하지 않을 오디오를 요청하는 것은 아무 이점 없이 생성 시간을 낭비합니다.
오디오 동작은 진화할 가능성이 가장 높은 영역 중 하나이므로, 사운드트랙 내용이나 프롬프트와의 관계에 대한 가정을 하드코딩하지 마세요. 현재 모델 문서를 읽고, 실제 작업으로 출력을 검증한 다음, 그 주변에 다운스트림 프로세스를 설계하세요.
해상도
더 높은 해상도는 프레임당 더 많은 픽셀과 상당히 더 많은 계산을 의미합니다. 실용적인 워크플로는 프롬프트와 프레임 선택을 조정하는 동안 중간 해상도로 반복하고, 그런 다음 승리한 구성을 최종 해상도로 다시 생성하는 것입니다. 좋은 결과를 다시 생성하는 것이 최상의 결과가 잘못된 설정에서 만들어졌음을 마지막에 발견하는 것보다 훨씬 저렴합니다.
기를 만한 몇 가지 습관:
- 제출 전 검증. 모델이 전달한 해상도를 지원하지 않으면, 몇 분 후 혼란스러운 작업 수준 실패가 아닌 명확한 제출 시 거부를 원합니다.
- 설정을 작업과 함께 저장. 여러 결과를 비교할 때 각 결과가 어떤 해상도와 오디오 선택에 의해 생성되었는지 알아야 합니다.
- 프레임 간 동등성을 가정하지 마세요. 큰 소스 이미지를 사용하는 두 프레임 작업은 단일 프레임 작업과 다르게 작동할 수 있습니다; 두 경로를 모두 테스트하세요.
코드에서 이들이 어디에 있어야 하는지
생성 옵션을 자체 객체로 그룹화하면 의도가 명확해지고 기본값을 한 곳에서 교체할 수 있습니다:
options = {
"resolution": "1080p", # confirm supported values in the model docs
"audio": True,
}
문서 값에 의존하는 줄에 주석을 추가하세요. 미래의 당신——또는 팀원——은 어떤 필드가 안전하고 어떤 필드가 출시 전에 참조 페이지와 대조하여 확인해야 하는지 즉시 구별할 수 있어야 합니다. 의문이 있을 때 HiAPI의 모델 문서가 사실의 출처이며, 예시 요청 본문이 아닙니다.
Python에서 완료 상태 폴링하기
폴링 코드는 대부분의 통합이 조용히 취약해지는 곳입니다. 목표는 매번 복사-붙여넣기하고 편집하는 스크립트가 아닌, 작업을 제출하고 합리적인 제한으로 기다리는 작고 재사용 가능한 클라이언트를 구축하는 것입니다.
최소 클라이언트 구조
import os, time, requests
BASE = os.environ["HIAPI_BASE_URL"]
KEY = os.environ["HIAPI_API_KEY"]
HEADERS = {"Authorization": f"Bearer {KEY}"}
def submit(payload: dict) -> str:
r = requests.post(f"{BASE}/v1/video/generations",
headers=HEADERS, json=payload, timeout=30)
r.raise_for_status()
return r.json()["id"]
def wait(task_id: str, interval: float = 5.0, max_wait: float = 600.0) -> dict:
deadline = time.monotonic() + max_wait
while time.monotonic() < deadline:
r = requests.get(f"{BASE}/v1/video/generations/{task_id}",
headers=HEADERS, timeout=30)
r.raise_for_status()
job = r.json()
if job["status"] in ("succeeded", "failed"):
return job
time.sleep(interval)
raise TimeoutError(f"task {task_id} not finished in {max_wait}s")
그 코드에서 대부분의 무게를 지탱하는 네 가지 세부 사항:
- 모든 HTTP 호출에 명시적 타임아웃 설정. 멈춘 요청은 실패한 요청보다 나쁩니다.
- 최대 대기 시간. 무한 루프는 멈춘 작업을 멈춘 서비스로 바꿉니다.
- 종료 상태 확인. 상태가 진정으로 최종일 때만 중지하며, 인식하지 못하는 상태를 포함한 다른 모든 것은 여전히 실행 중으로 취급하세요.
- 전체 작업 객체 반환. 호출자는 일반적으로 불리언 값이 아닌 출력 URL과 모든 오류 세부 정보를 필요로 합니다.
폴링 리듬
비디오 작업의 경우 5초가 합리적인 기본값입니다. 200ms마다 폴링하면 렌더링이 어차피 몇 분 걸리므로 이점 없이 할당량을 소비합니다. 많은 작업을 제출하는 경우 폴링 루프를 요청 핸들러가 아닌 워커에 두고, 장기 실행 작업에 대해 약간의 백오프를 적용하세요.
연결하기
payload = {
"model": "kling-3.0-omni/image-to-video",
"input": {"image": first_frame_url, "prompt": prompt},
"options": options,
}
job = wait(submit(payload))
if job["status"] == "failed":
raise RuntimeError(job.get("error") or "generation failed")
print(job["output"]["url"])
submit이 일반 문자열을 반환하고 wait가 dict를 반환하므로, 각 절반을 독립적으로 테스트할 수 있습니다: 제출 응답을 모의하여 폴링 로직을 테스트하고, submit을 단독으로 호출하여 요청 본문을 라이브 API와 대조하여 확인하세요.
일반적인 오류 디버깅하기
오류는 세 가지 계층에 집중되며, 계층을 식별하는 것이 진단의 대부분입니다.
계층 1: 제출 시 거부
이들은 작업이 존재하기 전에 4xx 응답으로 나타납니다. 일반적인 원인:
- 인증——헤더 누락, bearer 토큰 형식 오류, 생각하는 환경에 내보내지지 않은 키.
- 요청 본문 구조——필드 철자 오류, 배열 위치에 문자열 사용, 옵션 중첩 수준 오류.
- 지원되지 않는 값——모델이 허용하지 않는 해상도 또는 오디오 조합.
- 리소스 문제——접근할 수 없거나, 만료되었거나, 이미지가 아닌 파일 URL.
오류 응답 본문을 읽으세요. API는 일반적으로 문제가 있는 필드를 지적하며, 가장 빠른 수정은 종종 메시지가 제안하는 것입니다. curl에서 실패한 호출을 재현하여 문제가 클라이언트 코드가 아닌 요청 본문에 있음을 확인하세요.
계층 2: 전송 문제
네트워크는 코드와 작업 수명 주기 사이에 있습니다.제출 호출의 타임아웃과 연결 재설정은 모호합니다: 작업이 생성되었을 수도 있고 아닐 수도 있습니다. 맹목적으로 재시도하면 중복 작업이 발생할 수 있습니다.
안전한 패턴은 멱등성이 안전한 작업만 재시도하고 모든 제출 시도와 응답을 기록하는 것입니다. 제출이 성공했는지 확실히 알 수 없다면, 다시 제출하기 전에 작업 기록을 확인하세요. 폴링 측면에서 단일 상태 확인 실패는 작업 실패가 아닙니다——예외를 잡고, 기다린 다음, 다시 물어보세요.
계층 3: 작업 수준 실패
이들은 원래 수락된 작업에 종료 상태로 도달합니다. 일반적으로 콘텐츠가 지정된 방식으로 생성될 수 없음을 의미합니다: 두 프레임이 너무 달라 보간할 수 없거나, 프롬프트가 소스 이미지와 조화될 수 없거나, 렌더링 중 내부 오류.
코드에서 명확히 구별하세요, 왜냐하면 해결책이 다르기 때문입니다.4xx는 요청을 수정하라는 의미입니다. 실패한 작업은 입력을 변경하거나 재시도하라는 의미입니다——동일한 요청 본문이 두 번 실패하면 재시도를 중단하고 무언가를 변경하세요: 프롬프트 단순화, 더 가까운 프레임 선택, 해상도 낮추기.
빠른 분류 체크리스트
- HTTP 상태가
4xx인가요? 요청 본문이나 자격 증명을 수정하세요; 폴링하지 마세요. - 제출은 성공했지만 작업이 완료되지 않나요? 대기 제한이 너무 짧거나 작업이 멈췄습니다——작업 ID를 기록하고 조사하세요, 영원히 루프하지 마세요.
- 작업이 실패했나요? 오류 세부 정보를 읽은 다음 입력을 조정하세요, 그대로 다시 제출하지 마세요.
- 성공했지만 비디오가 잘못되었나요? 그것은 API 문제가 아닌 프롬프트 및 프레임 선택 문제입니다.
출시: 프로덕션 체크리스트
사용자에게 공개하기 전에 조용히 실패하는 부분을 강화하세요.
구성. base URL과 API 키를 환경 변수 또는 비밀 관리자에 보관하고, 소스 코드에는 절대 넣지 마세요. 둘 중 하나가 누락되면 첫 사용자 요청 시가 아닌 시작 시 빠르게 실패하세요.
타임아웃 및 재시도. 모든 아웃바운드 호출에 명시적 타임아웃이 필요합니다. 반복이 허용되는 곳에서만 제출을 재시도하고, 폴링 재시도는 안전한 것으로 취급하세요——멱등 상태 읽기. 총 대기 시간을 제한하고 호출자에게 명확한 타임아웃을 노출하세요.
작업 ID가 기록입니다. 작업 ID를 제출된 요청 본문과 함께 영속화하세요: 프레임, 프롬프트, 해상도, 오디오 선택, 타임스탬프. 누군가 2주 후에 비디오가 왜 잘못 보이는지 물으면, 그 행이 모든 답입니다.
출력은 임시적입니다. 반환된 비디오 URL을 임시로 취급하세요. 작업이 성공하자마자 자체 영구 저장소에 다운로드하고 저장하며, 저장 위치를 작업에 기록하세요.
비용 의식. 비디오 생성은 생성된 출력에 대해 청구되므로 해상도, 지속 시간, 생성 횟수가 중요한 레버입니다. 낮은 해상도로 반복하고, 의식적으로 최종 버전을 생성하며, 설정을 기록하여 지출을 사용 사례로 귀속시킬 수 있도록 하세요, 청구서에서야 발견하지 않도록 하세요.
관측 가능성. 제출 시와 종료 상태 시에 작업 ID, 지연 시간, 상태를 포함한 로그 줄을 출력하세요. 각 모델의 간단한 성공률 지표는 프롬프트 변경이나 옵션 조정이 언제 작업 실패를 일으키기 시작하는지 알려줍니다.
예제가 아닌 문서와 대조하여 검증하세요. 오디오, 해상도 또는 프레임 입력이 관련된 모든 출시 전에 모델 참조 페이지에서 필드 이름과 허용 값을 확인하세요, 왜냐하면 이러한 설정이 드리프트할 가능성이 가장 높기 때문입니다.
클라이언트, 폴링 루프, 이러한 보호 장치를 갖추면 kling-3.0-omni/image-to-video는 작동하기를 기도하는 스크립트가 아닌 예측 가능한 구성 요소가 됩니다.
관련 글
모든 아티클 보기 →-
튜토리얼
HiAPI API로 hailuo-2.3-fast/image-to-video 호출하는 방법: curl과 Python 실전
빠르고 저렴한 이미지-투-비디오 등급의 첫 실행 요청 — 모델 ID부터 MP4 다운로드까지
-
튜토리얼
HiAPI API로 hailuo-2.3/text-to-video를 호출하는 방법: curl, Python 및 실행 가능한 요청 예시
-
튜토리얼
HiAPI에서 Kandinsky 6.0 Pro 텍스트-투-비디오 사용하기: curl 및 Python 튜토리얼
요청 우선 실전 데모: 프롬프트에서 비디오 클립까지의 호출 구성, 요청 제출, 완료 상태 폴링 및 결과 다운로드