> [Site index](https://perfectvector.com/llms.txt) — available pages and descriptions.

# Pythonと画像ベクター化APIでSVGを保存する方法：テストと変換の復旧

> PythonからPNG、JPEG、WebPをベクター化APIに送信してSVGを保存します。テスト応答の確認と、接続切れ後に既存の変換を取り直す方法も解説します。

Source: https://perfectvector.com/ja/blog/vectorize-image-python-api

Language: ja
Author: Jay
Published: 2026-11-09T08:00:00+09:00

Pythonスクリプトでラスター画像をPerfectVectorのベクター化APIに送り、返されたSVGを元画像と同じ場所に保存できます。次の例では、ダウンロード前に変換IDを表示します。接続が途切れたら、そのIDまたは自分で決めたリクエストキーから結果を取り直せます。

## テストキーと画像を1枚用意する

[Developer APIのページ](https://perfectvector.com/account/developers)でテストキーを作成します。ターミナルで環境変数 `PERFECTVECTOR_API_KEY` に設定し、スクリプトやバージョン管理には入れないでください。プロジェクトのPython環境で `python -m pip install requests` を実行します。

最初は `logo.png` という512 × 512ピクセルのロゴなど、単一フレームのPNG、JPEG、WebPを使います。APIは5 MiB以下で、各辺が100～4,096ピクセルの画像を受け付けます。テストモードはアップロードを検証し、「TEST MODE」と記された固定のSVGを無料で返します。このファイルでリクエストとダウンロードを確認できます。トレースの品質は、自分の画像を本番変換して評価します。[PerfectVector APIのテストモード](https://perfectvector.com/docs/api/test-mode)

テストキーでPythonスクリプトを実行すると、ダウンロードしたSVGを正常に解析できました。同じリクエストキーで同じアップロードを再送すると、どちらも同じ変換IDが返りました。

**処理の流れ**

![ローカルのラスター画像が識別タグ付きのクラウドリクエストを経由し、ベクターファイルとしてディスクに戻ります。](https://perfectvector.com/blog/vectorize-image-python-api/workflow.webp)

*リクエストキーをアップロードとひも付け、SVGをダウンロードする前に変換IDを保存します。*

## Pythonで画像を送信してSVGを保存する

次のコードを `vectorize.py` として保存します。Requestsの `files` 引数でマルチパートのアップロードを作成し、元画像のデータを `image` フォームフィールドに入れます。[Requestsのマルチパートアップロード](https://requests.readthedocs.io/en/latest/user/quickstart/#post-a-multipart-encoded-file)

```python
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ではこれを*冪等性キー*と呼び、同じアップロードの再送を1つの変換にひも付けます。例では `logo-asset-0001` を使います。画像や操作が異なる場合は、別の値を使います。[PerfectVectorの安全な再試行](https://perfectvector.com/docs/api/idempotency)

```bash
python vectorize.py logo.png logo-asset-0001
```

テストが成功すると変換IDとバイト数が表示され、`logo.png` の隣に `logo.svg` が保存されます。`logo.svg` を開いて、サンプルが表示されるか確認します。スクリプトは新しいSVGのダウンロードが終わると、同名の既存SVGを置き換えます。初回は作業用フォルダーで試してください。

スクリプトはサーバーに、未完了の変換を返すまで最大10秒待つよう求めます。`queued` と `processing` の変換は約2秒間隔で確認し、`succeeded` になってからダウンロードします。テスト変換はすぐに終わります。本番ワーカーに組み込む前に、ローカルのテストデータで未完了の応答を再現して、ポーリングの分岐を確認します。[PerfectVectorの待機と非同期処理](https://perfectvector.com/docs/api/waiting-and-async)

## タイムアウト後に既存の変換を取り直す

Pythonが変換IDを表示していれば、`GET /v1/vectorizations/{id}` でそのIDの状態を調べます。成功後、同じアカウントとモードで `GET /v1/vectorizations/{id}/result` を呼び、SVGをダウンロードします。結果のリンクは完了から24時間で期限が切れるため、後から使うなら自分のストレージにコピーしてください。[PerfectVectorの結果ダウンロード](https://perfectvector.com/docs/api/results)

IDが表示される前にPythonが止まったら、最初のリクエストから24時間以内に、同じファイルのデータと同じ冪等性キーを使ってコマンドを実行し直します。最初の送信が受理されていれば、APIは既存の変換を返します。この期間を過ぎると、同じキーで送っても新しい変換が始まる場合があります。[PerfectVectorの安全な再試行](https://perfectvector.com/docs/api/idempotency)

| 表示された内容                                              | 確認すること                                                         |
| ---------------------------------------------------- | -------------------------------------------------------------- |
| `401 invalid_api_key`                                | Pythonが使う環境に有効なテストキーを設定します。キーを失効させた場合は、同じモードで作り直します。           |
| `415 unsupported_media_type` または `422 invalid_image` | 元ファイルを開き、実際の形式とピクセル寸法を確認します。修正した画像を保存し、そのアップロードには別のキーを使います。    |
| 変換IDの後に `processing_failed`                          | APIは変換の記録を作成しましたが、画像をトレースできませんでした。元画像を調べ、修正したファイルを別の操作として送ります。 |
| `409 idempotency_conflict`                           | 同じキーで異なる画像データまたはオプションを使っています。元ファイルで復旧するか、新しい入力に新しいキーを割り当てます。   |

サポートに連絡する場合は、例外に表示されたリクエストIDか、スクリプトが表示した変換IDを控えます。[APIエラーのリファレンス](https://perfectvector.com/docs/api/errors)で安全に再試行できるエラーを確認できます。

## よくある質問

### 同じPythonスクリプトでJPEGやWebPもベクター化できますか？

はい。最初の引数にJPEGまたはWebPのファイルを指定します。ファイルサイズ、寸法、単一フレームの条件は同じで、出力の拡張子はSVGです。

### このPythonの例でフォルダー全体を処理できますか？

まず1件のアップロードとダウンロードを確認してください。フォルダーを処理する場合は、各ファイルのキー、変換ID、出力パスを永続的なキューに記録します。PerfectVectorは既定で1アカウントにつき同時に1件の本番変換を許可するので、次を送る前に前の変換が終わるまで待ちます。[PerfectVector APIの制限](https://perfectvector.com/docs/api/limits)

## 参考資料

1. [Requests — クイックスタート](https://requests.readthedocs.io/en/latest/user/quickstart/) — マルチパートのファイル、タイムアウト、バイト応答。
2. [PerfectVector — テストモード](https://perfectvector.com/docs/api/test-mode) — アップロードの制限、固定のテストSVG、クレジットの扱い。
3. [PerfectVector — 待機と非同期処理](https://perfectvector.com/docs/api/waiting-and-async) — サーバーの待機指定、ポーリング、テストリクエストの完了時点。
4. [PerfectVector — 冪等性](https://perfectvector.com/docs/api/idempotency) — キーの有効期間、適用範囲、競合、再送条件。
5. [PerfectVector — 結果](https://perfectvector.com/docs/api/results) — 結果のエンドポイント、認証、有効期限。
6. [PerfectVector — エラー](https://perfectvector.com/docs/api/errors) — HTTPの問題コードと復旧方法。
7. [PerfectVector — 制限](https://perfectvector.com/docs/api/limits) — 本番の既定同時実行数とファイル制限。

***

[PerfectVector APIのページでテストキーを取得](https://perfectvector.com/ja/api)し、手元の画像1枚でスクリプトを実行します。保存されたSVGが開けることと、ターミナルに変換IDが表示されることを確認してください。

## Explore

- [Read the HTML article](https://perfectvector.com/ja/blog/vectorize-image-python-api)
- [2026年版おすすめAI画像ベクター化ツール：用途別の結論](https://perfectvector.com/ja/blog/best-ai-vectorizers-2026.md)
- [Claude CodeとMCPで画像フォルダーを一括SVG化：保存先の設計と検査](https://perfectvector.com/ja/blog/batch-vectorize-images-claude-code-mcp.md)
- [Product facts](https://perfectvector.com/product-facts.md)
- [FAQ](https://perfectvector.com/faq.md)
- [Pricing and credits](https://perfectvector.com/pricing.md)
