Python에서 이미지 벡터화 API로 SVG 변환하기
Python으로 PNG, JPEG, WebP를 벡터화 API에 보내 SVG를 저장합니다. 테스트 응답을 확인하고 연결이 끊겨도 기존 변환을 이어가는 방법을 살펴봅니다.
목차
Python 스크립트로 래스터 이미지를 PerfectVector 벡터화 API에 보내고 원본 옆에 SVG를 저장할 수 있습니다. 아래 예제는 파일을 받기 전에 변환 ID부터 출력합니다. 연결이 끊기면 그 ID로 상태를 확인하거나, 미리 정해 둔 요청 키로 같은 변환을 다시 조회할 수 있습니다.
테스트 키와 이미지 한 장 준비하기
Developer API 페이지에서 테스트 키를 만드세요. 터미널 환경 변수 PERFECTVECTOR_API_KEY에 설정하고, 스크립트나 버전 관리에는 넣지 마세요. 프로젝트의 Python 환경에서 python -m pip install requests로 Requests를 설치합니다.
처음에는 logo.png 같은 512 × 512 로고를 사용해 보세요. API는 최대 5 MiB의 단일 프레임 PNG, JPEG, WebP를 받으며, 가로와 세로는 각각 100~4096픽셀이어야 합니다. 테스트 모드는 업로드를 검사한 뒤 “TEST MODE”가 표시된 고정 SVG를 무료로 반환합니다. 이 파일로 요청과 다운로드를 확인하고, 실제 이미지의 벡터화 품질은 실사용 모드에서 평가하세요. PerfectVector API 테스트 모드
테스트 키로 아래 Python 스크립트를 실행해 SVG가 정상적으로 파싱되는지 확인했습니다. 같은 요청 키로 동일한 파일을 다시 보내자 두 번 모두 같은 변환 ID가 반환됐습니다.

Python으로 이미지를 보내고 SVG 저장하기
아래 코드를 vectorize.py로 저장하세요. Requests의 files 인자는 원본 바이트를 image 폼 필드에 넣어 멀티파트 요청을 만듭니다. Requests 멀티파트 업로드
import os
import sys
import time
from pathlib import Path
import requests
API = "https://api.perfectvector.com/v1"
AUTH = {"Authorization": f"Bearer {os.environ['PERFECTVECTOR_API_KEY']}"}
def checked(response):
content_type = response.headers.get("Content-Type", "").split(";")[0]
if response.status_code >= 400 and content_type == "application/problem+json":
problem = response.json()
raise RuntimeError(f"{problem['code']} (request {problem['request_id']})")
response.raise_for_status()
return response
def vectorize(source, destination, operation_id):
with source.open("rb") as image:
response = checked(requests.post(
f"{API}/vectorizations",
headers={**AUTH, "Idempotency-Key": operation_id, "Prefer": "wait=10"},
files={"image": (source.name, image)},
timeout=30,
))
conversion = response.json()
conversion_id = conversion["id"]
print(f"Conversion ID: {conversion_id}", flush=True)
deadline = time.monotonic() + 720
while conversion["status"] in {"queued", "processing"}:
if time.monotonic() >= deadline:
raise TimeoutError(f"Stopped polling {conversion_id}")
time.sleep(2)
conversion = checked(requests.get(
f"{API}/vectorizations/{conversion_id}", headers=AUTH, timeout=30,
)).json()
if conversion["status"] != "succeeded":
error = conversion["results"][0].get("error") or {}
raise RuntimeError(f"{conversion_id}: {error.get('code', conversion['status'])}")
svg = checked(requests.get(
f"{API}/vectorizations/{conversion_id}/result", headers=AUTH, timeout=30,
))
if svg.headers.get("Content-Type", "").split(";")[0] != "image/svg+xml":
raise ValueError("Expected an SVG response")
partial = destination.with_suffix(".svg.part")
partial.write_bytes(svg.content)
partial.replace(destination)
print(f"{destination} saved ({len(svg.content)} bytes)")
if __name__ == "__main__":
source = Path(sys.argv[1])
if source.suffix.lower() not in {".png", ".jpg", ".jpeg", ".webp"}:
raise SystemExit("Choose a PNG, JPEG or WebP file")
if source.stat().st_size > 5 * 1024 * 1024:
raise SystemExit("Choose a file no larger than 5 MiB")
vectorize(source, source.with_suffix(".svg"), sys.argv[2])logo.png가 있는 폴더에서 실행하세요. 실행 전에 이 변환에 사용할 ID를 정하고 기록해 둡니다. API에서 멱등성 키라고 부르는 값으로, 같은 업로드를 다시 보내도 하나의 변환으로 처리할 수 있습니다. 예제에서는 logo-asset-0001을 사용합니다. 다른 이미지나 작업에는 새 키를 쓰세요. PerfectVector 안전한 재시도
python vectorize.py logo.png logo-asset-0001테스트가 성공하면 변환 ID와 파일 크기(바이트)가 출력되고 logo.png 옆에 logo.svg가 생깁니다. logo.svg를 열어 샘플이 제대로 표시되는지 확인하세요. 스크립트는 다운로드가 끝나면 같은 이름의 기존 SVG를 덮어쓰므로 첫 실행은 임시 폴더에서 하는 편이 좋습니다.
스크립트는 완료되지 않은 변환을 반환하기 전 최대 10초 기다리도록 서버에 요청합니다. queued와 processing 상태에서는 약 2초 간격으로 상태를 확인하고, succeeded일 때만 다운로드합니다. 테스트 변환은 즉시 끝납니다. 실사용 환경에 적용하기 전, 완료되지 않은 상태의 응답을 로컬 테스트 데이터로 만들어 상태 확인 로직을 검증하세요. PerfectVector 대기와 비동기 처리
시간 초과 후 기존 변환 이어가기
Python에서 이미 변환 ID를 출력했다면 GET /v1/vectorizations/{id}로 상태를 확인하세요. 성공하면 같은 계정과 키 모드로 GET /v1/vectorizations/{id}/result를 호출해 SVG를 받습니다. 결과 링크는 변환이 끝난 뒤 24시간 후 만료되므로 나중에도 필요한 파일은 직접 보관하세요. PerfectVector 결과 다운로드
ID가 출력되기 전에 Python이 멈췄다면 첫 요청부터 24시간 안에 같은 파일 바이트와 같은 멱등성 키로 명령을 다시 실행하세요. 첫 업로드가 접수됐다면 API가 기존 변환을 반환합니다. 이 시간이 지나면 같은 키로 제출해도 새 변환이 시작될 수 있습니다. PerfectVector 안전한 재시도
| 메시지 | 확인할 사항 |
|---|---|
401 invalid_api_key | Python이 실행되는 환경에 유효한 테스트 키를 설정하세요. 이전 키를 폐기했다면 같은 모드에서 새 키를 만드세요. |
415 unsupported_media_type 또는 422 invalid_image | 원본의 실제 형식과 픽셀 크기를 확인하세요. 파일을 수정했다면 새 키로 업로드하세요. |
변환 ID 뒤에 processing_failed | 변환 레코드는 만들어졌지만 이미지를 벡터화하지 못했습니다. 원본을 살펴보고 수정한 파일로 새 작업을 시작하세요. |
409 idempotency_conflict | 같은 키로 다른 이미지 바이트나 옵션을 보냈습니다. 원본과 기존 옵션으로 복구하거나, 새 입력에 새 키를 쓰세요. |
지원팀에 문의할 때는 예외에 표시된 요청 ID나 스크립트가 출력한 변환 ID를 보관하세요. API 오류 문서에서 안전하게 재시도할 수 있는 오류를 확인할 수 있습니다.
자주 묻는 질문
같은 Python 스크립트로 JPEG나 WebP도 벡터화할 수 있나요?
네. 첫 번째 인자로 JPEG 또는 WebP 파일을 넘기세요. 크기, 가로·세로 길이, 단일 프레임 조건이 동일하게 적용되며 출력 확장자는 SVG입니다.
이 Python 예제를 폴더 전체에 적용할 수 있나요?
먼저 한 파일로 업로드와 다운로드를 확인하세요. 폴더를 처리하려면 파일마다 요청 키, 변환 ID, 출력 경로를 재시작 후에도 남는 큐에 기록하세요. PerfectVector의 기본 설정은 계정당 실사용 변환을 한 번에 하나만 허용하므로, 현재 변환이 끝난 뒤 다음 파일을 제출하세요. PerfectVector API 제한
출처
- Requests — 빠른 시작 — 멀티파트 파일, 시간 제한, 응답 바이트.
- PerfectVector — 테스트 모드 — 업로드 제한, 고정 테스트 SVG, 테스트 크레딧 처리.
- PerfectVector — 대기와 비동기 처리 — 서버 대기 설정, 상태 확인, 테스트 요청 완료 시점.
- PerfectVector — 멱등성 — 키 유효 시간과 범위, 충돌 및 재요청 규칙.
- PerfectVector — 결과 — 결과 엔드포인트, 인증, 만료.
- PerfectVector — 오류 — HTTP 오류 코드와 복구 방법.
- PerfectVector — 제한 — 기본 동시 변환 한도와 파일 제한.
PerfectVector API 페이지에서 테스트 키를 발급받고 직접 준비한 이미지로 스크립트를 실행해 보세요. 저장한 SVG가 열리고 터미널에 변환 ID가 출력되는지 확인하세요.


