튜토리얼
hiapi API에서 happyhorse-1.1/image-to-video 호출하기: curl 및 Python 가이드
이 엔드포인트의 역할과 사용 시점
happyhorse-1.1/image-to-video는 단일 정적 이미지를 짧은 영상으로 변환합니다. 이 엔드포인트에 첫 프레임 이미지를 보내면 모델이 해당 프레임에서부터 앞으로 애니메이션을 생성합니다. 이것의 실질적 의미는 연속성에 있습니다. 시작 이미지의 피사체, 구도, 외관이 생성된 클립으로 이어집니다. 이것이 우리가 여기서 말하는 정체성 보존입니다. 모델이 텍스트 프롬프트만으로 완전히 새로운 장면을 만들어내는 것이 아니라, 이미 이미지로 만들어 둔 장면을 이어가는 것입니다.
따라서 시각적 정체성이 즉흥성보다 중요할 때 이 엔드포인트가 매우 적합합니다:
- 참조 정지 이미지(인물 사진, 제품 사진, 캐릭터 설정화)가 이미 있고 그 정지 이미지에 충실한 움직임을 생성하고 싶을 때.
- 다른 모든 소재를 먼저 이미지 형태로 디자인하는 파이프라인에서 단편 영상을 제작할 때.
- 스토리보드 프레임의 동적 스토리보드나 모션 프리뷰가 필요할 때.
모델이 장면을 처음부터 자유롭게 재해석하길 원하거나, 출력을 고정할 정지 이미지가 없을 때는 덜 적합합니다. 이런 경우 이미지 우선 워크플로는 보통 먼저 기준 이미지를 생성한 뒤 그 결과를 이 엔드포인트에 넘기는 것을 의미합니다.
호출 자체는 비동기입니다. 작업을 제출한 뒤 영상이 준비될 때까지 폴링합니다. 이 가이드의 나머지 부분에서는 이 생애주기를 처음부터 끝까지 다룹니다.
요청을 보내기 전에
첫 호출 전에 두 가지를 준비해야 합니다.
API 키
모든 호출은 hiapi 플랫폼을 통해 이루어지며, API 키는 bearer 자격 증명으로 첨부됩니다. 키를 소스 코드 관리가 아닌 환경 변수에 보관하면 동일한 코드를 로컬 개발과 CI에서 그대로 사용할 수 있습니다:
export HIAPI_API_KEY="your_key_here"
Python에서는 런타임에 os.environ["HIAPI_API_KEY"]로 읽습니다. 원시 헤더 값을 절대 기록하지 마세요.
참조 가능한 첫 프레임 이미지
이 엔드포인트에는 시작 이미지가 필요합니다. 플랫폼이 가져올 수 있는 URL로 전달할지, 업로드/베이스64 인코딩된 소재로 전달할지는 계정과 엔드포인트 문서가 지원하는 방식에 따라 미리 정하세요. 중요한 것은 해당 참조가 제출 시점에 안정적이고 접근 가능해야 한다는 점입니다. 작업이 대기열에 들어갈 수 있다면 5분 후에 만료되는 서명 URL은 좋지 않은 선택입니다.
호출 전에 예상 출력의 가로세로 비율과 길이를 아는 것도 도움이 됩니다. 첫 프레임이 보통 이를 제약하기 때문입니다. 이 결정을 미리 해두면 나중에 다시 제출하는 일을 피할 수 있습니다.
키를 export하고 이미지 참조가 확정되면 제출할 준비가 된 것입니다.
첫 프레임 입력 구성
첫 프레임은 모델이 그 이후에 생성하는 모든 것의 기준점입니다. 실제로는 정체성 계약으로 생각해야 합니다. 해당 이미지에서 명확히 보이는 모든 것(얼굴, 의상, 로고, 색상 구성, 카메라 각도)이 모델이 따르야 할 기준입니다. 정지 이미지의 어떤 세부가 흐릿하거나 가려져 있다면 출력도 흐릿해집니다.
특정 모델 파라미터와 관계없이 다음 준비 원칙이 적용됩니다:
- 선명하고 조명이 좋은 프레임을 선택하세요. 압축 아티팩트와 심한 노이즈는 모델이 보존할 수 있는 내용을 줄입니다. 선명하고 균일하게 조명된 이미지가 극적이지만 흐릿한 이미지보다 더 나은 기준점입니다.
- 움직임이 시작되길 원하는 위치에 피사체를 배치하세요. 정지 이미지에서 자르고 구도 잡는 것이 모델이 다시 프레이밍하길 기대하는 것보다 효율적입니다.
- 예상 출력의 가로세로 비율을 유지하세요. 최종 영상이 가로형이라면 가로형 기준 이미지를 준비하세요. 나중에 채워 넣어도 잃어버린 구도는 복구되지 않습니다.
- 모순되는 단서를 피하세요. 한 가지 의미로 읽히면서 화면 밖 동작을 암시하는 정지 이미지는 모델에게 불안정한 시작점을 줍니다.
엔드포인트 문서에 없는 모델 전용 파라미터를 가정하지 마세요. 가장 안전한 방법은 이미지 자체가 의도를 담게 하고, 요청 필드는 명시적으로 다루는 내용만 처리하게 하는 것입니다.
curl로 사용 가능한 요청 보내기
작업 제출은 POST 한 번이면 됩니다. 구조는 다음과 같습니다: 엔드포인트에 인증된 요청을 보내고, JSON 본문에 모델 식별자와 이미지 입력을 담습니다.
curl -sS -X POST "https://api.hiapi.ai/v1/video/generations" \
-H "Authorization: Bearer $HIAPI_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "happyhorse-1.1/image-to-video",
"input": {
"image": "https://your-bucket.example.com/first-frame.jpg"
}
}'
단계별 설명:
- 엔드포인트. POST 대상은 hiapi API의 영상 생성 라우트입니다. 여러 환경을 대상으로 스크립트를 작성한다면 변수에 넣으세요.
- 인증 헤더.
Authorization: Bearer $HIAPI_API_KEY— 셸이 앞서 export한 환경 변수를 확장합니다. - 콘텐츠 타입. 본문이 JSON이므로
application/json입니다. - 요청 본문.
model은happyhorse-1.1/image-to-video를 선택하고,input.image는 첫 프레임 참조입니다. 계정에서 허용되는 정확한 이미지 필드명과 구조는 엔드포인트 참조 문서를 확인하세요.
성공 응답은 영상 자체가 아니라 작업 핸들입니다. 식별자와 상태 필드(보통 queued 또는 processing 같은 값)를 예상하세요. 이 ID를 기록해 두세요. 이후 단계에서 폴링에 사용합니다. 스크립트 작성 전에 구조를 확인할 수 있도록 명령을 한 번 실행하고 응답을 출력하세요.
Python으로 동일한 요청 보내기
Python 버전은 새로운 통합이 아니라 직역 이식입니다. 같은 라우트, 같은 헤더, 같은 JSON 본문입니다.
import os
import requests
API_KEY = os.environ["HIAPI_API_KEY"]
URL = "https://api.hiapi.ai/v1/video/generations"
payload = {
"model": "happyhorse-1.1/image-to-video",
"input": {
"image": "https://your-bucket.example.com/first-frame.jpg"
},
}
resp = requests.post(
URL,
headers={
"Authorization": f"Bearer {API_KEY}",
"Content-Type": "application/json",
},
json=payload,
timeout=60,
)
resp.raise_for_status()
job = resp.json()
print(job)
매핑 설명:
json=payload를 사용하는requests는 curl의-d문자열처럼 딕셔너리를 직렬화합니다.json=을 사용한다면Content-Type을 수동으로 설정하지 마세요. 라이브러리가 처리합니다. 위의 명시적 헤더는 무해하지만 불필요합니다.raise_for_status()는 존재하지 않는 작업을 폴링하기 시작하기 전에 HTTP 계층 실패를 조기에 예외로 전환합니다.timeout은 제출 호출에 대한 클라이언트 보호일 뿐입니다. 생성은 서버에서 실행되며 이에 구속되지 않습니다.
payload를 변수에 담아 재사용하세요. 나중에 모델이나 이미지를 바꿀 때 두 개의 평행한 구현이 아니라 하나의 딕셔너리만 편집하면 됩니다.
비동기 작업 처리와 폴링
이미지-영상 생성은 요청/응답 주기보다 오래 걸립니다. 따라서 API는 즉시 작업 참조를 반환하고 나중에 다시 조회할 것을 기대합니다. 생애주기는 제출, ID 수신, 상태 폴링, 결과 획득입니다.
제출 응답에서 작업 ID를 추출하세요. 필드명은 해당 엔드포인트의 문서화된 응답 스키마에 따라 다르므로, 값이 아니라 키 조회를 하드코딩하도록 한 번 읽어 두세요:
job_id = job["id"] # 정확한 필드는 엔드포인트 문서를 확인하세요
그런 다음 간격을 두고 폴링합니다:
import time
poll_url = f"https://api.hiapi.ai/v1/video/generations/{job_id}"
while True:
status = requests.get(
poll_url,
headers={"Authorization": f"Bearer {API_KEY}"},
timeout=30,
).json()
if status["status"] == "succeeded":
break
if status["status"] == "failed":
raise RuntimeError(status)
time.sleep(5)
합리적인 폴링 규칙:
- 타이트한 루프가 아닌 고정 간격으로 폴링하세요. 이 규모의 작업에는 검사 사이 몇 초면 충분합니다. 엔드포인트를 마구 두드리면 부하만 늘어나고 결과가 더 빨리 나오지 않습니다.
- 총 대기 시간을 제한하세요. 상한 없는
while True는 언젠가 반드시 발생할 정지입니다. 경과 시간을 추적하고 합리적인 예산을 넘으면 크게 실패하세요. - 두 가지 종료 상태를 모두 처리하세요. 성공과 실패 모두 답입니다. 알 수 없는 상태 문자열은 비종료로 취급하되 기록하여 패턴 변화를 알아차릴 수 있게 하세요.
- 하나의 작업을 여러 병렬 워커가 폴링하지 마세요. 작업당 하나의 폴러를 두거나 대기열로 조정하세요.
상태가 종료에 도달하면 결과를 다운로드합니다.
출력 다운로드 및 저장
완료된 영상은 완료된 작업 응답에 소재로 노출됩니다. 보통 URL이며 때로는 만료 시간이 있습니다. 성공적인 폴링 후 첫 단계는 해당 참조를 가져와 바이트를 직접 제어하는 저장소로 복사하는 것입니다.
video_url = status["output"]["video_url"] # 실제 응답 형태를 확인하세요
with requests.get(video_url, stream=True, timeout=120) as r:
r.raise_for_status()
with open(f"out/{job_id}.mp4", "wb") as f:
for chunk in r.iter_content(chunk_size=1 << 20):
f.write(chunk)
모든 파이프라인에 적용되는 저장 지침:
- 영구 자산은 링크가 아닌 복사본으로. 서명 또는 시간 제한 URL은 전송 수단이지 저장소가 아닙니다. 파일을 영속화한 뒤 데이터베이스에 자신의 객체 키를 작업 ID와 함께 저장하세요.
- 큰 파일은 스트리밍하세요.
iter_content는 메모리를 안정적으로 유지합니다. 전체 영상을 변수에 로드하면 메모리 상한이 소재 크기에 묶입니다. - 출처를 기록하세요.
job_id, 입력 이미지 참조, 모델 식별자를 소재와 함께 저장하세요. 클립을 재현해야 할 때 그 기록이 레시피입니다. - 쓰기 전에 HTTP 상태를 확인하세요. 오류 응답으로 인한 부분 쓰기는 깔끔한 실패보다 나쁩니다. 유효한 파일처럼 보이기 때문입니다.
파일이 디스크나 객체 저장소에 저장되면 파이프라인이 닫히고 다음 프레임을 처리할 수 있습니다.
주의해야 할 오류와 함정
이 엔드포인트의 대부분 실패는 예측 가능합니다. 간단한 목록은 다음과 같습니다:
- 첫 프레임 입력 형식 오류 또는 접근 불가. 제출 거부의 가장 흔한 원인입니다. 이미지 URL이 공개적으로 해석되는지, 형식이 엔드포인트에서 허용되는지, payload에 이미지 필드가 올바르게 중첩되었는지 확인하세요. curl로 호출해 재현하여 인증 문제와 payload 문제를 구분하세요.
- 작업이 존재하기 전에 폴링. 잘못된 필드에서 ID를 읽거나 제출 응답과 일치하지 않는 라우트를 폴링하면 작업 실패처럼 보이는 404가 발생합니다. 제출 응답을 한 번 출력하고 거기에 맞춰 키 조회를 고정하세요.
- 무한 대기. 타임아웃이 없으면 멈춘 작업이 워커를 무기한 매답니다. 예산을 설정하고 실패시키고 경고하세요.
- 소재 링크 분실. 생성은 성공했지만 URL을 한 번 소비한 뒤 복사하지 않았습니다. 가져올 때 바이트를 저장하고 자신의 키를 보관하세요. 반환된 링크를 장기 저장소로 의존하지 마세요.
- 인증 유출. 키를 노트북에 붙여 넣고 실수로 커밋하는 것은 반복되는 문제입니다. 환경에서 로드하고 의심되면 교체하세요.
- 문서화되지 않은 파라미터 가정. 나열되지 않은 파라미터가 필요하다면 그것은 존재하지 않습니다. 첫 프레임 이미지와 문서화된 필드로만 의도를 표현하세요.
이것들을 처리하면 비동기 흐름은 평범해집니다. 그것이 바로 프로덕션 파이프라인에서 원하는 것입니다. 엔드포인트별 필드명과 허용 값은 구축 중에 엔드포인트 참조 문서를 열어 두세요.
관련 글
모든 아티클 보기 →-
튜토리얼
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 튜토리얼
요청 우선 실전 데모: 프롬프트에서 비디오 클립까지의 호출 구성, 요청 제출, 완료 상태 폴링 및 결과 다운로드