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

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를 발생시킵니다. 따라서 이 상태들을 처리하는 곳에서 예외를 잡으세요.
| 상태 | 의미 | 코드가 할 일 |
|---|---|---|
200 | data에 URL이 담긴 이미지 응답. | 파일을 하나씩 내려받음. |
202 | Job 봉투. 대기 시간 안에 이미지가 준비되지 않았음. | status_url을 폴링한 뒤 result_url을 읽음. |
400 unsupported_parameter | 보낸 필드를 모델이 나열하지 않음. | 본문을 고침. 같은 요청은 다시 실패함. |
402 insufficient_credits | 생성에 필요한 잔액이 부족함. | 멈추고 대시보드에서 충전. API에는 충전 호출이 없음. |
429 queue_full 또는 rate_limited | 워크스페이스 큐가 가득 찼거나 요청이 너무 많음. | retry-after가 있으면 그 값을 따라 백오프. |
502 | 대기 시간 안에 생성이 실패함. 과금되지 않음. | 현재 코드에서는 본문에 Job의 오류 code와 status_url이 담김. |
출처
관련 글
개발자 카테고리의 다른 글
- JavaScript 음성 인식 API: Node.js에서 오디오를 텍스트로
서버의 JavaScript 코드에서 음성 인식 API를 호출하세요. Node.js에서 Sume SDK로 오디오 파일 URL을 보내고, Job을 기다린 뒤 텍스트를 읽습니다.
- Python 음성 인식(STT): 오디오를 타임스탬프와 함께 텍스트로
Python에서 Requests로 음성을 텍스트로 변환하세요. 오디오 URL을 보내고 Job을 폴링한 뒤 전사문과 단어별 타임스탬프를 읽는 Sume STT 1.0 스크립트입니다.
- 브라우저에서 Sume API 호출 시 CORS 오류: 해결 방법
브라우저는 내 사이트에서 api.sume.com으로 직접 보내는 호출을 차단하며, API 키는 프론트엔드 코드에 절대 넣으면 안 됩니다. 서버에서 Sume를 호출해 프록시하세요.
- Sume API 엔드포인트 목록: 경로, 스코프, 멱등성
Sume API의 공개 경로를 계열별로 정리한 색인입니다. 키가 필요 없는 경로, 계열별 스코프, Idempotency-Key 적용 위치, 계열별 설명 글을 담았습니다.
작성자 Sume