Python 이미지 생성 API: AI 이미지 생성하고 저장하기

Python에서 Requests로 이미지를 생성하세요. 이미지 API에 프롬프트를 POST하고, 200이면 URL을 읽고 202면 Job을 폴링한 뒤 파일을 하나씩 저장합니다.

읽는 시간 5분Sume
전체 글

Python으로 이미지를 생성하려면 Requests 라이브러리로 모델과 프롬프트를 담은 JSON 본문을 이미지 생성 API에 POST한 뒤, 응답에 담긴 이미지 URL을 하나씩 내려받아 디스크에 쓰세요. Sume의 POST /v1/images는 최대 30초 동안 기다렸다가 이미지 URL과 함께 200을 반환합니다. 그때까지 이미지가 준비되지 않으면 202와 함께 Job을 반환하며, 이 Job은 /v1/jobs/{id}/status에서 폴링하고 /v1/jobs/{id}/result에서 읽습니다.

Sume 관련 사실은 Image API (영문)와 Job과 결과 (영문) 문서에서, Requests 동작은 Requests 빠른 시작에서 가져왔으며, 모두 2026-09-27에 확인했습니다. Sume SDK는 TypeScript용이므로 Python에서는 REST API를 직접 호출합니다. Image API 문서에 실린 Requests 예제도 그렇게 합니다. 영상은 Python Text-to-Video API를 참고하세요.

Python으로 이미지를 어떻게 생성하나요?

키는 환경 변수에서 읽고, model과 prompt를 보내고, timeout을 30초 대기보다 길게 설정하세요. Requests는 타임아웃을 설정하지 않으면 타임아웃되지 않습니다.

  • json=은 본문을 대신 인코딩하고 JSON 콘텐츠 타입을 설정하며, raise_for_status()는 성공이 아닌 상태 코드에서 HTTPError를 발생시킵니다.
  • POST에 Idempotency-Key를 보내세요. 그러면 같은 키로 재시도했을 때 두 번째 Job을 과금하는 대신 원래 Job이 반환됩니다.
  • data의 각 항목에는 url과 media_type이 있습니다. URL은 Sume가 호스팅하는 서명된 URL이므로 보관할 파일은 내려받으세요. 바이트는 response.content로 얻습니다.
import os
import requests

API = "https://api.sume.com/v1/images"
HEADERS = {"Authorization": f"Bearer {os.environ['SUME_API_KEY']}"}
payload = {
    "model": "bytedance-seed/seedream-4.5",
    "prompt": "a red panda astronaut floating in space, studio lighting",
    "aspect_ratio": "1:1",
    "output_format": "png",
}

response = requests.post(
    API,
    headers={**HEADERS, "Idempotency-Key": "red-panda-001"},
    json=payload,
    timeout=60,
)
response.raise_for_status()

if response.status_code == 200:
    for i, image in enumerate(response.json()["data"]):
        file = requests.get(image["url"], timeout=60)
        with open(f"image-{i}.png", "wb") as f:
            f.write(file.content)

API가 200 대신 202를 반환하면 어떻게 하나요?

본문 형태가 아니라 상태 코드를 확인하세요. 200은 이미지 응답이고 202는 Job 봉투입니다. 4K, 높은 quality, 큰 n 같은 느린 설정일수록 202를 반환할 가능성이 큽니다. next_poll_after_seconds를 지키며 terminal이 true가 될 때까지 Job의 status_url을 폴링한 뒤, 결과의 artifacts에서 이미지 URL을 읽으세요. 다시 제출하지 마세요. 클라이언트 타임아웃은 Job을 취소하지 않으며, Job은 계속 실행되고 여전히 과금됩니다.

import time

job = response.json()["data"]  # the 202 job envelope
while True:
    status = requests.get(job["status_url"], headers=HEADERS, timeout=30).json()["data"]
    if status["terminal"]:
        break
    time.sleep(status["next_poll_after_seconds"] or 5)

if status["sume_status"] == "completed":
    result = requests.get(job["result_url"], headers=HEADERS, timeout=30).json()["data"]
    urls = [a["url"] for a in result["result"]["artifacts"] if a["type"] == "image"]

Python 코드는 어떤 응답을 처리해야 하나요?

필수 필드는 model과 prompt뿐이며, 그 밖의 필드는 모델이 나열하는 것이어야 합니다. 선택 필드는 레퍼런스 이미지 기반 이미지 생성 API에서 하나씩 설명합니다. 클라이언트 쪽 타임아웃이나 연결 끊김 뒤에는 같은 Idempotency-Key 헤더로 다시 보내세요. 두 번째 Job을 과금하는 대신 원래 Job이 반환됩니다.

오류는 code, message, request_id를 담은 error 객체가 있는 JSON이며, 예제의 raise_for_status()는 아래의 성공이 아닌 상태마다 HTTPError를 발생시킵니다. 따라서 이 상태들을 처리하는 곳에서 예외를 잡으세요.

Image API (영문), 오류와 요청 한도 (영문), 결제와 크레딧 문서 기준, 2026-09-27 확인.
상태의미코드가 할 일
200data에 URL이 담긴 이미지 응답.파일을 하나씩 내려받음.
202Job 봉투. 대기 시간 안에 이미지가 준비되지 않았음.status_url을 폴링한 뒤 result_url을 읽음.
400 unsupported_parameter보낸 필드를 모델이 나열하지 않음.본문을 고침. 같은 요청은 다시 실패함.
402 insufficient_credits생성에 필요한 잔액이 부족함.멈추고 대시보드에서 충전. API에는 충전 호출이 없음.
429 queue_full 또는 rate_limited워크스페이스 큐가 가득 찼거나 요청이 너무 많음.retry-after가 있으면 그 값을 따라 백오프.
502대기 시간 안에 생성이 실패함. 과금되지 않음.현재 코드에서는 본문에 Job의 오류 code와 status_url이 담김.

출처

관련 글

개발자 카테고리의 다른 글

개발자 글 전체 보기

작성자 Sume